[anjuta-extras] scintilla: Update to scintilla 3.3.0
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta-extras] scintilla: Update to scintilla 3.3.0
- Date: Sun, 31 Mar 2013 17:32:13 +0000 (UTC)
commit c75d60ea6c8af0d1824155d08aec39887728638b
Author: Sébastien Granjoux <seb sfo free fr>
Date: Sun Mar 31 19:06:48 2013 +0200
scintilla: Update to scintilla 3.3.0
plugins/scintilla/properties/styles.properties | 26 +-
plugins/scintilla/scintilla/Makefile.am | 1 +
plugins/scintilla/scintilla/gtk/PlatGTK.cxx | 21 +-
plugins/scintilla/scintilla/gtk/ScintillaGTK.cxx | 25 +-
plugins/scintilla/scintilla/include/Face.py | 8 +-
plugins/scintilla/scintilla/include/HFacer.py | 5 +
plugins/scintilla/scintilla/include/ILexer.h | 21 +-
plugins/scintilla/scintilla/include/Platform.h | 11 +-
plugins/scintilla/scintilla/include/SciLexer.h | 10 +
plugins/scintilla/scintilla/include/Scintilla.h | 30 ++
.../scintilla/scintilla/include/Scintilla.iface | 150 +++++-
plugins/scintilla/scintilla/lexers.make | 4 +
plugins/scintilla/scintilla/lexers/LexBash.cxx | 156 ++++++-
plugins/scintilla/scintilla/lexers/LexCPP.cxx | 204 ++++++--
plugins/scintilla/scintilla/lexers/LexCSS.cxx | 29 +-
plugins/scintilla/scintilla/lexers/LexFortran.cxx | 33 +-
plugins/scintilla/scintilla/lexers/LexHTML.cxx | 19 +-
plugins/scintilla/scintilla/lexers/LexLaTeX.cxx | 539 ++++++++++++++++++++
plugins/scintilla/scintilla/lexers/LexLua.cxx | 2 +-
plugins/scintilla/scintilla/lexers/LexMySQL.cxx | 185 +++++---
plugins/scintilla/scintilla/lexers/LexOthers.cxx | 394 +--------------
plugins/scintilla/scintilla/lexers/LexPO.cxx | 213 ++++++++
plugins/scintilla/scintilla/lexers/LexRuby.cxx | 14 +-
plugins/scintilla/scintilla/lexers/LexSQL.cxx | 33 +-
plugins/scintilla/scintilla/lexers/LexYAML.cxx | 2 +-
plugins/scintilla/scintilla/lexlib/CharacterSet.h | 37 ++-
plugins/scintilla/scintilla/lexlib/LexAccessor.h | 39 ++-
plugins/scintilla/scintilla/lexlib/LexerBase.cxx | 2 +-
plugins/scintilla/scintilla/lexlib/StyleContext.h | 97 +++-
plugins/scintilla/scintilla/lexlib/SubStyles.h | 162 ++++++
.../patches/scintilla-remove-deprecated.diff | 14 -
plugins/scintilla/scintilla/src/AutoComplete.cxx | 17 +-
plugins/scintilla/scintilla/src/AutoComplete.h | 10 +
plugins/scintilla/scintilla/src/CallTip.cxx | 18 +-
plugins/scintilla/scintilla/src/CallTip.h | 5 +
plugins/scintilla/scintilla/src/Catalogue.cxx | 2 +-
plugins/scintilla/scintilla/src/CellBuffer.cxx | 114 ++++-
plugins/scintilla/scintilla/src/CellBuffer.h | 8 +
plugins/scintilla/scintilla/src/CharClassify.cxx | 16 +
plugins/scintilla/scintilla/src/CharClassify.h | 1 +
.../scintilla/scintilla/src/ContractionState.cxx | 2 +-
plugins/scintilla/scintilla/src/Document.cxx | 159 +++++--
plugins/scintilla/scintilla/src/Document.h | 20 +-
plugins/scintilla/scintilla/src/Editor.cxx | 532 ++++++++++++++------
plugins/scintilla/scintilla/src/Editor.h | 64 ++-
plugins/scintilla/scintilla/src/Indicator.cxx | 51 ++-
plugins/scintilla/scintilla/src/LineMarker.cxx | 17 +-
plugins/scintilla/scintilla/src/LineMarker.h | 2 +-
plugins/scintilla/scintilla/src/PerLine.cxx | 11 +-
plugins/scintilla/scintilla/src/PerLine.h | 2 +-
plugins/scintilla/scintilla/src/PositionCache.h | 4 +
plugins/scintilla/scintilla/src/RESearch.cxx | 2 +-
plugins/scintilla/scintilla/src/RunStyles.cxx | 1 +
plugins/scintilla/scintilla/src/RunStyles.h | 2 +
plugins/scintilla/scintilla/src/ScintillaBase.cxx | 137 ++++-
plugins/scintilla/scintilla/src/UniConversion.h | 13 +
plugins/scintilla/scintilla/src/ViewStyle.cxx | 34 +-
plugins/scintilla/scintilla/src/ViewStyle.h | 15 +-
plugins/scintilla/scintilla/src/XPM.cxx | 13 +-
plugins/scintilla/scintilla/src/XPM.h | 6 +-
60 files changed, 2826 insertions(+), 938 deletions(-)
---
diff --git a/plugins/scintilla/properties/styles.properties b/plugins/scintilla/properties/styles.properties
index cf87bdc..98b59dc 100644
--- a/plugins/scintilla/properties/styles.properties
+++ b/plugins/scintilla/properties/styles.properties
@@ -222,7 +222,7 @@ mmx2_instruction=pavgb pavgw \
emmx_instruction=paddsiw psubsiw \
pmulhrw pmachriw pmulhriw \
pmagw pdistib paveb \
- pmvzb pmvnzb pmvlzb pmvgezb
+ pmvzb pmvnzb pmvlzb pmvgezb
k3d_instruction=pfacc pfadd pfsub pfsubr pfmul \
pfcmpeq pfcmpge pfcmpgt \
@@ -239,7 +239,7 @@ k3dgeode_instruction=pfrsqrtv pfrcpv
k3dprefetch_instruction=prefetch prefetchw
sse_instruction=addss addps subss subps \
- mulss mulps divss divps sqrtss sqrtps \
+ mulss mulps divss divps sqrtss sqrtps \
rcpss rcpps rsqrtss rsqrtps \
maxss maxps minss minps \
cmpss comiss ucomiss cmpps \
@@ -3100,7 +3100,7 @@ lexer.$(file.patterns.f77)=f77
keywordclass.fortran=access action advance allocatable allocate \
apostrophe assign assignment associate asynchronous backspace \
bind blank blockdata call case character class close common \
-complex contains continue cycle data deallocate decimal delim \
+complex contains continue critical cycle data deallocate decimal delim \
default dimension direct do dowhile double doubleprecision else \
elseif elsewhere encoding end endassociate endblockdata enddo \
endfile endforall endfunction endif endinterface endmodule endprogram \
@@ -4553,7 +4553,6 @@ keywords6.$(file.patterns.m3)= author authors file brief date proc param result
# Default fonts
#
-#font.module.base=!Monaco # The best font for programmers, in my opinion of course :)
font.module.base=$(font.base)
font.modula.code=font:$(font.module.base),size:10
font.modula.comment=font:$(font.module.base),size:10,italics
@@ -5155,7 +5154,7 @@ command.help.*.properties="file://$(SciteDefaultHome)/SciTEDoc.html#property-$(C
command.help.subsystem.*.properties=2
if PLAT_WIN
- command.go.*.bat=$(FileNameExt)
+ command.go.*.bat="$(FileNameExt)"
command.name.0.*.bat=Execute Selection
command.0.*.bat=$(CurrentSelection)
command.name.1.*.mak=nmake
@@ -5308,7 +5307,7 @@ system syswrite tell telldir tie tied time times truncate \
uc ucfirst umask undef unless unlink unpack unshift untie until \
use utime values vec wait waitpid wantarray warn while write \
xor \
-given when default break say state UNITCHECK
+given when default break say state UNITCHECK __SUB__ fc
keywords.$(file.patterns.awk)=\
BEGIN END \
@@ -6153,6 +6152,13 @@ if PLAT_GTK
command.name.2.*.rb=Code Profiler
command.2.*.rb=ruby -r profile $(FileNameExt)
+if PLAT_MAC
+ command.go.*.rb=ruby $(FileNameExt)
+ command.name.1.*.rb=Check Syntax
+ command.1.*.rb=ruby -cw $(FileNameExt)
+ command.name.2.*.rb=Code Profiler
+ command.2.*.rb=ruby -r profile $(FileNameExt)
+
###############################################################################
@@ -8218,13 +8224,15 @@ keywords.$(file.patterns.yaml)=true false yes no
# Comment keyword error
style.cpp.18=$(style.anjuta.comment)
# Libraries symbols
- style.cpp.19=$(style.anjuta.syskeyword)
+#style.cpp.19=$(style.anjuta.syskeyword)
# Raw strings for C++0x
style.cpp.20=$(style.anjuta.string)
# Triple-quoted strings for Vala
style.cpp.21=$(style.anjuta.string)
# Hash-quoted strings for Pike
style.cpp.22=$(style.anjuta.string)
+# Preprocessor stream comment
+ style.cpp.23=$(style.anjuta.preprocessor)
# White space
style.cpp.64=$(style.anjuta.whitespace)
# Comment: /* */.
@@ -8269,6 +8277,8 @@ keywords.$(file.patterns.yaml)=true false yes no
style.cpp.85=$(style.anjuta.string)
# Hash-quoted strings for Pike
style.cpp.86=$(style.anjuta.string)
+# Preprocessor stream comment
+ style.cpp.87=$(style.anjuta.preprocessor)
@@ -8635,6 +8645,8 @@ keywords.$(file.patterns.yaml)=true false yes no
style.errorlist.20=$(style.anjuta.error)
# Text matched with find in files and message part of GCC errors
style.errorlist.21=$(style.anjuta.normal)
+# GCC showing include path to following error
+ style.errorlist.22=$(style.anjuta.error)
diff --git a/plugins/scintilla/scintilla/Makefile.am b/plugins/scintilla/scintilla/Makefile.am
index b517ebc..74eb600 100644
--- a/plugins/scintilla/scintilla/Makefile.am
+++ b/plugins/scintilla/scintilla/Makefile.am
@@ -86,6 +86,7 @@ libanjuta_scintilla_la_SOURCES =\
lexlib/SparseState.h \
lexlib/StyleContext.cxx\
lexlib/StyleContext.h\
+ lexlib/SubStyles.h \
lexlib/WordList.cxx \
lexlib/WordList.h \
gtk/Converter.h \
diff --git a/plugins/scintilla/scintilla/gtk/PlatGTK.cxx b/plugins/scintilla/scintilla/gtk/PlatGTK.cxx
index d98c235..c228047 100644
--- a/plugins/scintilla/scintilla/gtk/PlatGTK.cxx
+++ b/plugins/scintilla/scintilla/gtk/PlatGTK.cxx
@@ -105,9 +105,11 @@ struct LOGFONT {
static GMutex *fontMutex = NULL;
static void InitializeGLIBThreads() {
+#if !GLIB_CHECK_VERSION(2,31,0)
if (!g_thread_supported()) {
g_thread_init(NULL);
}
+#endif
}
#endif
@@ -115,7 +117,12 @@ static void FontMutexAllocate() {
#if USE_LOCK
if (!fontMutex) {
InitializeGLIBThreads();
+#if GLIB_CHECK_VERSION(2,31,0)
+ fontMutex = g_new(GMutex, 1);
+ g_mutex_init(fontMutex);
+#else
fontMutex = g_mutex_new();
+#endif
}
#endif
}
@@ -123,7 +130,12 @@ static void FontMutexAllocate() {
static void FontMutexFree() {
#if USE_LOCK
if (fontMutex) {
+#if GLIB_CHECK_VERSION(2,31,0)
+ g_mutex_clear(fontMutex);
+ g_free(fontMutex);
+#else
g_mutex_free(fontMutex);
+#endif
fontMutex = NULL;
}
#endif
@@ -143,8 +155,7 @@ static void FontMutexUnlock() {
#endif
}
-// On GTK+ 1.x holds a GdkFont* but on GTK+ 2.x can hold a GdkFont* or a
-// PangoFontDescription*.
+// Holds a PangoFontDescription*.
class FontHandle {
XYPOSITION width[128];
encodingType et;
@@ -541,6 +552,8 @@ void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
PLATFORM_ASSERT(wid);
context = cairo_reference(reinterpret_cast<cairo_t *>(sid));
pcontext = gtk_widget_create_pango_context(PWidget(wid));
+ // update the Pango context in case sid isn't the widget's surface
+ pango_cairo_update_context(context, pcontext);
layout = pango_layout_new(pcontext);
cairo_set_line_width(context, 1);
createdGC = true;
@@ -554,6 +567,8 @@ void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID
PLATFORM_ASSERT(wid);
context = cairo_reference(surfImpl->context);
pcontext = gtk_widget_create_pango_context(PWidget(wid));
+ // update the Pango context in case surface_ isn't the widget's surface
+ pango_cairo_update_context(context, pcontext);
PLATFORM_ASSERT(pcontext);
layout = pango_layout_new(pcontext);
PLATFORM_ASSERT(layout);
@@ -1858,7 +1873,7 @@ void ListBoxX::RegisterImage(int type, const char *xpm_data) {
}
void ListBoxX::RegisterRGBAImage(int type, int width, int height, const unsigned char *pixelsImage) {
- RegisterRGBA(type, new RGBAImage(width, height, pixelsImage));
+ RegisterRGBA(type, new RGBAImage(width, height, 1.0, pixelsImage));
}
void ListBoxX::ClearRegisteredImages() {
diff --git a/plugins/scintilla/scintilla/gtk/ScintillaGTK.cxx
b/plugins/scintilla/scintilla/gtk/ScintillaGTK.cxx
index be007e7..20c398b 100644
--- a/plugins/scintilla/scintilla/gtk/ScintillaGTK.cxx
+++ b/plugins/scintilla/scintilla/gtk/ScintillaGTK.cxx
@@ -296,7 +296,7 @@ private:
static gboolean TimeOut(ScintillaGTK *sciThis);
static gboolean IdleCallback(ScintillaGTK *sciThis);
static gboolean StyleIdle(ScintillaGTK *sciThis);
- virtual void QueueStyling(int upTo);
+ virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo);
static void PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis);
#if GTK_CHECK_VERSION(3,0,0)
@@ -1138,6 +1138,7 @@ void ScintillaGTK::ScrollText(int linesToMove) {
//Platform::DebugPrintf("ScintillaGTK::ScrollText %d %d %0d,%0d %0d,%0d\n", linesToMove, diff,
// rc.left, rc.top, rc.right, rc.bottom);
GtkWidget *wi = PWidget(wText);
+ NotifyUpdateUI();
if (IS_WIDGET_REALIZED(wi)) {
gdk_window_scroll(WindowFromWidget(wi), 0, -diff);
@@ -1213,6 +1214,10 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
modified = true;
}
#endif
+ if (modified && (paintState == painting)) {
+ paintState = paintAbandoned;
+ }
+
return modified;
}
@@ -2736,7 +2741,9 @@ int ScintillaGTK::TimeOut(ScintillaGTK *sciThis) {
gboolean ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
// Idler will be automatically stopped, if there is nothing
// to do while idle.
+#ifndef GDK_VERSION_3_6
gdk_threads_enter();
+#endif
bool ret = sciThis->Idle();
if (ret == false) {
// FIXME: This will remove the idler from GTK, we don't want to
@@ -2744,23 +2751,29 @@ gboolean ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
// returns false (although, it should be harmless).
sciThis->SetIdle(false);
}
+#ifndef GDK_VERSION_3_6
gdk_threads_leave();
+#endif
return ret;
}
gboolean ScintillaGTK::StyleIdle(ScintillaGTK *sciThis) {
+#ifndef GDK_VERSION_3_6
gdk_threads_enter();
- sciThis->IdleStyling();
+#endif
+ sciThis->IdleWork();
+#ifndef GDK_VERSION_3_6
gdk_threads_leave();
+#endif
// Idler will be automatically stopped
return FALSE;
}
-void ScintillaGTK::QueueStyling(int upTo) {
- Editor::QueueStyling(upTo);
- if (!styleNeeded.active) {
+void ScintillaGTK::QueueIdleWork(WorkNeeded::workItems items, int upTo) {
+ Editor::QueueIdleWork(items, upTo);
+ if (!workNeeded.active) {
// Only allow one style needed to be queued
- styleNeeded.active = true;
+ workNeeded.active = true;
g_idle_add_full(G_PRIORITY_HIGH_IDLE,
reinterpret_cast<GSourceFunc>(StyleIdle), this, NULL);
}
diff --git a/plugins/scintilla/scintilla/include/Face.py b/plugins/scintilla/scintilla/include/Face.py
index 97b700d..855d632 100644
--- a/plugins/scintilla/scintilla/include/Face.py
+++ b/plugins/scintilla/scintilla/include/Face.py
@@ -12,7 +12,7 @@ def decodeFunction(featureVal):
nameIdent, params = rest.split("(")
name, value = nameIdent.split("=")
params, rest = params.split(")")
- param1, param2 = params.split(",")[0:2]
+ param1, param2 = params.split(",")
return retType, name, value, param1, param2
def decodeEvent(featureVal):
@@ -60,7 +60,11 @@ class Face:
currentCommentFinished = 1
featureType, featureVal = line.split(" ", 1)
if featureType in ["fun", "get", "set"]:
- retType, name, value, param1, param2 =
decodeFunction(featureVal)
+ try:
+ retType, name, value, param1, param2 =
decodeFunction(featureVal)
+ except ValueError:
+ print("Failed to decode %s" % line)
+ raise
p1 = decodeParam(param1)
p2 = decodeParam(param2)
self.features[name] = {
diff --git a/plugins/scintilla/scintilla/include/HFacer.py b/plugins/scintilla/scintilla/include/HFacer.py
index 074ce96..aa6b0f0 100755
--- a/plugins/scintilla/scintilla/include/HFacer.py
+++ b/plugins/scintilla/scintilla/include/HFacer.py
@@ -20,9 +20,13 @@ def printLexHFile(f,out):
out.write("#define " + name + " " + v["Value"] + "\n")
def printHFile(f,out):
+ previousCategory = ""
for name in f.order:
v = f.features[name]
if v["Category"] != "Deprecated":
+ if v["Category"] == "Provisional" and previousCategory != "Provisional":
+ out.write("#ifndef SCI_DISABLE_PROVISIONAL\n")
+ previousCategory = v["Category"]
if v["FeatureType"] in ["fun", "get", "set"]:
featureDefineName = "SCI_" + name.upper()
out.write("#define " + featureDefineName + " " + v["Value"] + "\n")
@@ -32,6 +36,7 @@ def printHFile(f,out):
elif v["FeatureType"] in ["val"]:
if not (Contains(name, "SCE_") or Contains(name, "SCLEX_")):
out.write("#define " + name + " " + v["Value"] + "\n")
+ out.write("#endif\n")
def CopyWithInsertion(input, output, genfn, definition):
copying = 1
diff --git a/plugins/scintilla/scintilla/include/ILexer.h b/plugins/scintilla/scintilla/include/ILexer.h
index e08b870..1260c13 100644
--- a/plugins/scintilla/scintilla/include/ILexer.h
+++ b/plugins/scintilla/scintilla/include/ILexer.h
@@ -18,7 +18,7 @@ namespace Scintilla {
#define SCI_METHOD
#endif
-enum { dvOriginal=0 };
+enum { dvOriginal=0, dvLineEnd=1 };
class IDocument {
public:
@@ -45,7 +45,12 @@ public:
virtual int SCI_METHOD GetLineIndentation(int line) = 0;
};
-enum { lvOriginal=0 };
+class IDocumentWithLineEnd : public IDocument {
+public:
+ virtual int SCI_METHOD LineEnd(int line) const = 0;
+};
+
+enum { lvOriginal=0, lvSubStyles=1 };
class ILexer {
public:
@@ -62,6 +67,18 @@ public:
virtual void * SCI_METHOD PrivateCall(int operation, void *pointer) = 0;
};
+class ILexerWithSubStyles : public ILexer {
+public:
+ virtual int SCI_METHOD LineEndTypesSupported() = 0;
+ virtual int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) = 0;
+ virtual int SCI_METHOD SubStylesStart(int styleBase) = 0;
+ virtual int SCI_METHOD SubStylesLength(int styleBase) = 0;
+ virtual void SCI_METHOD FreeSubStyles() = 0;
+ virtual void SCI_METHOD SetIdentifiers(int style, const char *identifiers) = 0;
+ virtual int SCI_METHOD DistanceToSecondaryStyles() = 0;
+ virtual const char * SCI_METHOD GetSubStyleBases() = 0;
+};
+
class ILoader {
public:
virtual int SCI_METHOD Release() = 0;
diff --git a/plugins/scintilla/scintilla/include/Platform.h b/plugins/scintilla/scintilla/include/Platform.h
index 4cd2c5c..70a9ccc 100644
--- a/plugins/scintilla/scintilla/include/Platform.h
+++ b/plugins/scintilla/scintilla/include/Platform.h
@@ -22,6 +22,7 @@
#define PLAT_WX 0
#define PLAT_QT 0
#define PLAT_FOX 0
+#define PLAT_NCURSES 0
#if defined(FOX)
#undef PLAT_FOX
@@ -31,14 +32,18 @@
#undef PLAT_WX
#define PLAT_WX 1
-#elif defined(GTK)
-#undef PLAT_GTK
-#define PLAT_GTK 1
+#elif defined(NCURSES)
+#undef PLAT_NCURSES
+#define PLAT_NCURSES 1
#elif defined(SCINTILLA_QT)
#undef PLAT_QT
#define PLAT_QT 1
+#elif defined(GTK)
+#undef PLAT_GTK
+#define PLAT_GTK 1
+
#if defined(__WIN32__) || defined(_MSC_VER)
#undef PLAT_GTK_WIN32
#define PLAT_GTK_WIN32 1
diff --git a/plugins/scintilla/scintilla/include/SciLexer.h b/plugins/scintilla/scintilla/include/SciLexer.h
index 7fc0719..44043fe 100644
--- a/plugins/scintilla/scintilla/include/SciLexer.h
+++ b/plugins/scintilla/scintilla/include/SciLexer.h
@@ -160,6 +160,7 @@
#define SCE_C_STRINGRAW 20
#define SCE_C_TRIPLEVERBATIM 21
#define SCE_C_HASHQUOTEDSTRING 22
+#define SCE_C_PREPROCESSORCOMMENT 23
#define SCE_D_DEFAULT 0
#define SCE_D_COMMENT 1
#define SCE_D_COMMENTLINE 2
@@ -476,6 +477,7 @@
#define SCE_ERR_TIDY 19
#define SCE_ERR_JAVA_STACK 20
#define SCE_ERR_VALUE 21
+#define SCE_ERR_GCC_INCLUDED_FROM 22
#define SCE_BAT_DEFAULT 0
#define SCE_BAT_COMMENT 1
#define SCE_BAT_WORD 2
@@ -1344,6 +1346,7 @@
#define SCE_MYSQL_USER2 19
#define SCE_MYSQL_USER3 20
#define SCE_MYSQL_HIDDENCOMMAND 21
+#define SCE_MYSQL_PLACEHOLDER 22
#define SCE_PO_DEFAULT 0
#define SCE_PO_COMMENT 1
#define SCE_PO_MSGID 2
@@ -1353,6 +1356,13 @@
#define SCE_PO_MSGCTXT 6
#define SCE_PO_MSGCTXT_TEXT 7
#define SCE_PO_FUZZY 8
+#define SCE_PO_PROGRAMMER_COMMENT 9
+#define SCE_PO_REFERENCE 10
+#define SCE_PO_FLAGS 11
+#define SCE_PO_MSGID_TEXT_EOL 12
+#define SCE_PO_MSGSTR_TEXT_EOL 13
+#define SCE_PO_MSGCTXT_TEXT_EOL 14
+#define SCE_PO_ERROR 15
#define SCE_PAS_DEFAULT 0
#define SCE_PAS_IDENTIFIER 1
#define SCE_PAS_COMMENT 2
diff --git a/plugins/scintilla/scintilla/include/Scintilla.h b/plugins/scintilla/scintilla/include/Scintilla.h
index 5a7bc75..dabab00 100644
--- a/plugins/scintilla/scintilla/include/Scintilla.h
+++ b/plugins/scintilla/scintilla/include/Scintilla.h
@@ -154,6 +154,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARKERDEFINEPIXMAP 2049
#define SCI_MARKERADDSET 2466
#define SCI_MARKERSETALPHA 2476
+#define SC_MAX_MARGIN 4
#define SC_MARGIN_SYMBOL 0
#define SC_MARGIN_NUMBER 1
#define SC_MARGIN_BACK 2
@@ -252,6 +253,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETCARETPERIOD 2075
#define SCI_SETCARETPERIOD 2076
#define SCI_SETWORDCHARS 2077
+#define SCI_GETWORDCHARS 2646
#define SCI_BEGINUNDOACTION 2078
#define SCI_ENDUNDOACTION 2079
#define INDIC_PLAIN 0
@@ -267,6 +269,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define INDIC_DOTS 10
#define INDIC_SQUIGGLELOW 11
#define INDIC_DOTBOX 12
+#define INDIC_SQUIGGLEPIXMAP 13
#define INDIC_MAX 31
#define INDIC_CONTAINER 8
#define INDIC0_MASK 0x20
@@ -385,6 +388,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_POSITIONFROMLINE 2167
#define SCI_LINESCROLL 2168
#define SCI_SCROLLCARET 2169
+#define SCI_SCROLLRANGE 2569
#define SCI_REPLACESEL 2170
#define SCI_SETREADONLY 2171
#define SCI_NULL 2172
@@ -690,6 +694,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_WORDRIGHTEND 2441
#define SCI_WORDRIGHTENDEXTEND 2442
#define SCI_SETWHITESPACECHARS 2443
+#define SCI_GETWHITESPACECHARS 2647
+#define SCI_SETPUNCTUATIONCHARS 2648
+#define SCI_GETPUNCTUATIONCHARS 2649
#define SCI_SETCHARSDEFAULT 2444
#define SCI_AUTOCGETCURRENT 2445
#define SCI_AUTOCGETCURRENTTEXT 2610
@@ -776,6 +783,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_ANNOTATIONGETVISIBLE 2549
#define SCI_ANNOTATIONSETSTYLEOFFSET 2550
#define SCI_ANNOTATIONGETSTYLEOFFSET 2551
+#define SCI_RELEASEALLEXTENDEDSTYLES 2552
+#define SCI_ALLOCATEEXTENDEDSTYLES 2553
#define UNDO_MAY_COALESCE 1
#define SCI_ADDUNDOACTION 2560
#define SCI_CHARPOSITIONFROMPOINT 2561
@@ -789,6 +798,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_SETADDITIONALCARETSVISIBLE 2608
#define SCI_GETADDITIONALCARETSVISIBLE 2609
#define SCI_GETSELECTIONS 2570
+#define SCI_GETSELECTIONEMPTY 2650
#define SCI_CLEARSELECTIONS 2571
#define SCI_SETSELECTION 2572
#define SCI_ADDSELECTION 2573
@@ -838,6 +848,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETIDENTIFIER 2623
#define SCI_RGBAIMAGESETWIDTH 2624
#define SCI_RGBAIMAGESETHEIGHT 2625
+#define SCI_RGBAIMAGESETSCALE 2651
#define SCI_MARKERDEFINERGBAIMAGE 2626
#define SCI_REGISTERRGBAIMAGE 2627
#define SCI_SCROLLTOSTART 2628
@@ -850,6 +861,10 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_FINDINDICATORSHOW 2640
#define SCI_FINDINDICATORFLASH 2641
#define SCI_FINDINDICATORHIDE 2642
+#define SCI_VCHOMEDISPLAY 2652
+#define SCI_VCHOMEDISPLAYEXTEND 2653
+#define SCI_GETCARETLINEVISIBLEALWAYS 2654
+#define SCI_SETCARETLINEVISIBLEALWAYS 2655
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
@@ -954,6 +969,21 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCN_AUTOCCANCELLED 2025
#define SCN_AUTOCCHARDELETED 2026
#define SCN_HOTSPOTRELEASECLICK 2027
+#ifndef SCI_DISABLE_PROVISIONAL
+#define SC_LINE_END_TYPE_DEFAULT 0
+#define SC_LINE_END_TYPE_UNICODE 1
+#define SCI_SETLINEENDTYPESALLOWED 2656
+#define SCI_GETLINEENDTYPESALLOWED 2657
+#define SCI_GETLINEENDTYPESACTIVE 2658
+#define SCI_GETLINEENDTYPESSUPPORTED 4018
+#define SCI_ALLOCATESUBSTYLES 4020
+#define SCI_GETSUBSTYLESSTART 4021
+#define SCI_GETSUBSTYLESLENGTH 4022
+#define SCI_FREESUBSTYLES 4023
+#define SCI_SETIDENTIFIERS 4024
+#define SCI_DISTANCETOSECONDARYSTYLES 4025
+#define SCI_GETSUBSTYLEBASES 4026
+#endif
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
/* These structures are defined to be exactly the same shape as the Win32
diff --git a/plugins/scintilla/scintilla/include/Scintilla.iface
b/plugins/scintilla/scintilla/include/Scintilla.iface
index 7abbb68..496f472 100644
--- a/plugins/scintilla/scintilla/include/Scintilla.iface
+++ b/plugins/scintilla/scintilla/include/Scintilla.iface
@@ -287,13 +287,13 @@ val SC_MASK_FOLDERS=0xFE000000
fun void MarkerDefine=2040(int markerNumber, int markerSymbol)
# Set the foreground colour used for a particular marker number.
-fun void MarkerSetFore=2041(int markerNumber, colour fore)
+set void MarkerSetFore=2041(int markerNumber, colour fore)
# Set the background colour used for a particular marker number.
-fun void MarkerSetBack=2042(int markerNumber, colour back)
+set void MarkerSetBack=2042(int markerNumber, colour back)
# Set the background colour used for a particular marker number when its folding block is selected.
-fun void MarkerSetBackSelected=2292(int markerNumber, colour back)
+set void MarkerSetBackSelected=2292(int markerNumber, colour back)
# Enable/disable highlight for current folding bloc (smallest one that contains the caret)
fun void MarkerEnableHighlight=2293(bool enabled,)
@@ -324,7 +324,9 @@ fun void MarkerDefinePixmap=2049(int markerNumber, string pixmap)
fun void MarkerAddSet=2466(int line, int set)
# Set the alpha used for a marker that is drawn in the text area, not the margin.
-fun void MarkerSetAlpha=2476(int markerNumber, int alpha)
+set void MarkerSetAlpha=2476(int markerNumber, int alpha)
+
+val SC_MAX_MARGIN=4
enu MarginType=SC_MARGIN_
val SC_MARGIN_SYMBOL=0
@@ -403,7 +405,7 @@ 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(,)
+fun void StyleClearAll=2050(,)
# Set the foreground colour of a style.
set void StyleSetFore=2051(int style, colour fore)
@@ -454,7 +456,7 @@ get int StyleGetSize=2485(int style,)
# Get the font of a style.
# Returns the length of the fontName
-fun int StyleGetFont=2486(int style, stringresult fontName)
+get int StyleGetFont=2486(int style, stringresult fontName)
# Get is a style to have its end of line filled or not.
get bool StyleGetEOLFilled=2487(int style,)
@@ -552,6 +554,10 @@ set void SetCaretPeriod=2076(int periodMilliseconds,)
# First sets defaults like SetCharsDefault.
set void SetWordChars=2077(, string characters)
+# Get the set of characters making up words for when moving or selecting by word.
+# Retuns the number of characters
+get int GetWordChars=2646(, stringresult characters)
+
# Start a sequence of actions that is undone and redone as a unit.
# May be nested.
fun void BeginUndoAction=2078(,)
@@ -574,6 +580,7 @@ val INDIC_DASH=9
val INDIC_DOTS=10
val INDIC_SQUIGGLELOW=11
val INDIC_DOTBOX=12
+val INDIC_SQUIGGLEPIXMAP=13
val INDIC_MAX=31
val INDIC_CONTAINER=8
val INDIC0_MASK=0x20
@@ -917,6 +924,11 @@ fun void LineScroll=2168(int columns, int lines)
# Ensure the caret is visible.
fun void ScrollCaret=2169(,)
+# Scroll the argument positions and the range between them into view giving
+# priority to the primary position then the secondary position.
+# This may be used to make a search match visible.
+fun void ScrollRange=2569(position secondary, position primary)
+
# Replace the selected text with the argument text.
fun void ReplaceSel=2170(, string text)
@@ -1108,7 +1120,7 @@ val SC_FOLDFLAG_LINEAFTER_CONTRACTED=0x0010
val SC_FOLDFLAG_LEVELNUMBERS=0x0040
# Set some style options for folding.
-fun void SetFoldFlags=2233(int flags,)
+set void SetFoldFlags=2233(int flags,)
# Ensure a particular line is visible by expanding any header line hiding it.
# Use the currently set visibility policy to determine which range to display.
@@ -1277,7 +1289,7 @@ set void SetMultiPaste=2614(int multiPaste,)
get int GetMultiPaste=2615(,)
# Retrieve the value of a tag from a regular expression search.
-fun int GetTag=2616(int tagNumber, stringresult tagValue)
+get int GetTag=2616(int tagNumber, stringresult tagValue)
# Make the target range start and end be the same as the selection range start and end.
fun void TargetFromSelection=2287(,)
@@ -1629,7 +1641,7 @@ fun void DelLineLeft=2395(,)
# Delete forwards from the current position to the end of the line.
fun void DelLineRight=2396(,)
-# Get and Set the xOffset (ie, horizonal scroll position).
+# Get and Set the xOffset (ie, horizontal scroll position).
set void SetXOffset=2397(int newOffset,)
get int GetXOffset=2398(,)
@@ -1663,7 +1675,7 @@ val CARET_JUMPS=0x10
# where most code reside, and the lines after the caret, eg. the body of a function.
val CARET_EVEN=0x08
-# Set the way the caret is kept visible when going sideway.
+# Set the way the caret is kept visible when going sideways.
# The exclusion zone is given in pixels.
fun void SetXCaretPolicy=2402(int caretPolicy, int caretSlop)
@@ -1800,15 +1812,25 @@ fun void WordRightEndExtend=2442(,)
# Should be called after SetWordChars.
set void SetWhitespaceChars=2443(, string characters)
+# Get the set of characters making up whitespace for when moving or selecting by word.
+get int GetWhitespaceChars=2647(, stringresult characters)
+
+# Set the set of characters making up punctuation characters
+# Should be called after SetWordChars.
+set void SetPunctuationChars=2648(, string characters)
+
+# Get the set of characters making up punctuation characters
+get int GetPunctuationChars=2649(, stringresult characters)
+
# Reset the set of characters for whitespace and word characters to the defaults.
fun void SetCharsDefault=2444(,)
# Get currently selected item position in the auto-completion list
-fun int AutoCGetCurrent=2445(,)
+get int AutoCGetCurrent=2445(,)
# Get currently selected item text in the auto-completion list
# Returns the length of the item text
-fun int AutoCGetCurrentText=2610(, stringresult s)
+get int AutoCGetCurrentText=2610(, stringresult s)
enu CaseInsensitiveBehaviour=SC_CASEINSENSITIVEBEHAVIOUR_
val SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE=0
@@ -1893,7 +1915,7 @@ get int GetIndicatorCurrent=2501(,)
# Set the value used for IndicatorFillRange
set void SetIndicatorValue=2502(int value,)
-# Get the current indicator vaue
+# Get the current indicator value
get int GetIndicatorValue=2503(,)
# Turn a indicator on over a range.
@@ -2047,6 +2069,12 @@ set void AnnotationSetStyleOffset=2550(int style,)
# Get the start of the range of style numbers used for annotations
get int AnnotationGetStyleOffset=2551(,)
+# Release all extended (>255) style numbers
+fun void ReleaseAllExtendedStyles=2552(,)
+
+# Allocate some extended (>255) style numbers and return the start of the range
+fun int AllocateExtendedStyles=2553(int numberStyles,)
+
val UNDO_MAY_COALESCE=1
# Add a container action to the undo stack
@@ -2086,14 +2114,17 @@ get bool GetAdditionalCaretsVisible=2609(,)
# How many selections are there?
get int GetSelections=2570(,)
+# Is every selected range empty?
+get bool GetSelectionEmpty=2650(,)
+
# Clear selections to a single empty stream selection
fun void ClearSelections=2571(,)
# Set a simple selection
-fun int SetSelection=2572(int caret,int anchor)
+fun int SetSelection=2572(int caret, int anchor)
# Add a selection
-fun int AddSelection=2573(int caret,int anchor)
+fun int AddSelection=2573(int caret, int anchor)
# Set the main selection
set void SetMainSelection=2574(int selection,)
@@ -2117,7 +2148,7 @@ set void SetSelectionNStart=2584(int selection, position pos)
get position GetSelectionNStart=2585(int selection,)
# Sets the position that ends the selection - this becomes the currentPosition.
-set void SetSelectionNEnd=2586(int selection, position pos,)
+set void SetSelectionNEnd=2586(int selection, position pos)
# Returns the position at the end of the selection.
get position GetSelectionNEnd=2587(int selection,)
@@ -2204,6 +2235,9 @@ set void RGBAImageSetWidth=2624(int width,)
# Set the height for future RGBA image data.
set void RGBAImageSetHeight=2625(int height,)
+# Set the scale factor in percent for future RGBA image data.
+set void RGBAImageSetScale=2651(int scalePercent,)
+
# Define a marker from RGBA data.
# It has the width and height from RGBAImageSetWidth/Height
fun void MarkerDefineRGBAImage=2626(int markerNumber, string pixels)
@@ -2221,7 +2255,7 @@ fun void ScrollToEnd=2629(,)
val SC_TECHNOLOGY_DEFAULT=0
val SC_TECHNOLOGY_DIRECTWRITE=1
-# Set the technolgy used.
+# Set the technology used.
set void SetTechnology=2630(int technology,)
# Get the tech.
@@ -2239,6 +2273,19 @@ fun void FindIndicatorFlash=2641(position start, position end)
# On OS X, hide the find indicator.
fun void FindIndicatorHide=2642(,)
+# Move caret to before first visible character on display line.
+# If already there move to first character on display line.
+fun void VCHomeDisplay=2652(,)
+
+# Like VCHomeDisplay but extending selection to new caret position.
+fun void VCHomeDisplayExtend=2653(,)
+
+# Is the caret line always visible?
+get bool GetCaretLineVisibleAlways=2654(,)
+
+# Sets the caret line to always visible.
+set void SetCaretLineVisibleAlways=2655(bool alwaysVisible,)
+
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
@@ -2270,11 +2317,11 @@ set void SetLexerLanguage=4006(, string language)
fun void LoadLexerLibrary=4007(, string path)
# Retrieve a "property" value previously set with SetProperty.
-fun int GetProperty=4008(string key, stringresult buf)
+get 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)
+get int GetPropertyExpanded=4009(string key, stringresult buf)
# Retrieve a "property" value previously set with SetProperty,
# interpreted as an int AFTER any "$()" variable replacement.
@@ -2311,7 +2358,7 @@ fun int DescribeKeyWordSets=4017(, stringresult descriptions)
# 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.
# One bit is set from each of SC_MOD_* and SC_PERFORMED_*.
-enu ModificationFlags=SC_MOD_ SC_PERFORMED_ SC_LAST
+enu ModificationFlags=SC_MOD_ SC_PERFORMED_ SC_MULTISTEPUNDOREDO SC_LASTSTEPINUNDOREDO SC_MULTILINEUNDOREDO
SC_STARTACTION SC_MODEVENTMASKALL
val SC_MOD_INSERTTEXT=0x1
val SC_MOD_DELETETEXT=0x2
val SC_MOD_CHANGESTYLE=0x4
@@ -2540,6 +2587,7 @@ val SCE_C_GLOBALCLASS=19
val SCE_C_STRINGRAW=20
val SCE_C_TRIPLEVERBATIM=21
val SCE_C_HASHQUOTEDSTRING=22
+val SCE_C_PREPROCESSORCOMMENT=23
# Lexical states for SCLEX_D
lex D=SCLEX_D SCE_D_
val SCE_D_DEFAULT=0
@@ -2590,10 +2638,10 @@ val SCE_TCL_WORD8=19
val SCE_TCL_COMMENT_BOX=20
val SCE_TCL_BLOCK_COMMENT=21
# Lexical states for SCLEX_HTML, SCLEX_XML
-lex HTML=SCLEX_HTML SCE_H
-lex XML=SCLEX_XML SCE_H
-lex ASP=SCLEX_ASP SCE_H
-lex PHP=SCLEX_PHP SCE_H
+lex HTML=SCLEX_HTML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
+lex XML=SCLEX_XML SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
+lex ASP=SCLEX_ASP SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
+lex PHP=SCLEX_PHP SCE_H_ SCE_HJ_ SCE_HJA_ SCE_HB_ SCE_HBA_ SCE_HP_ SCE_HPHP_ SCE_HPA_
val SCE_H_DEFAULT=0
val SCE_H_TAG=1
val SCE_H_TAGUNKNOWN=2
@@ -2893,6 +2941,7 @@ val SCE_ERR_ABSF=18
val SCE_ERR_TIDY=19
val SCE_ERR_JAVA_STACK=20
val SCE_ERR_VALUE=21
+val SCE_ERR_GCC_INCLUDED_FROM=22
# Lexical states for SCLEX_BATCH
lex Batch=SCLEX_BATCH SCE_BAT_
val SCE_BAT_DEFAULT=0
@@ -3376,6 +3425,7 @@ val SCE_KIX_FUNCTIONS=8
val SCE_KIX_OPERATOR=9
val SCE_KIX_IDENTIFIER=31
# Lexical states for SCLEX_GUI4CLI
+lex Gui4Cli=SCLEX_GUI4CLI SCE_GC_
val SCE_GC_DEFAULT=0
val SCE_GC_COMMENTLINE=1
val SCE_GC_COMMENTBLOCK=2
@@ -3884,6 +3934,7 @@ val SCE_MYSQL_USER1=18
val SCE_MYSQL_USER2=19
val SCE_MYSQL_USER3=20
val SCE_MYSQL_HIDDENCOMMAND=21
+val SCE_MYSQL_PLACEHOLDER=22
# Lexical state for SCLEX_PO
lex Po=SCLEX_PO SCE_PO_
val SCE_PO_DEFAULT=0
@@ -3895,6 +3946,13 @@ val SCE_PO_MSGSTR_TEXT=5
val SCE_PO_MSGCTXT=6
val SCE_PO_MSGCTXT_TEXT=7
val SCE_PO_FUZZY=8
+val SCE_PO_PROGRAMMER_COMMENT=9
+val SCE_PO_REFERENCE=10
+val SCE_PO_FLAGS=11
+val SCE_PO_MSGID_TEXT_EOL=12
+val SCE_PO_MSGSTR_TEXT_EOL=13
+val SCE_PO_MSGCTXT_TEXT_EOL=14
+val SCE_PO_ERROR=15
# Lexical states for SCLEX_PASCAL
lex Pascal=SCLEX_PASCAL SCE_PAS_
val SCE_PAS_DEFAULT=0
@@ -4206,6 +4264,50 @@ evt void AutoCCancelled=2025(void)
evt void AutoCCharDeleted=2026(void)
evt void HotSpotReleaseClick=2027(int modifiers, int position)
+cat Provisional
+
+# Line end types which may be used in addition to LF, CR, and CRLF
+# SC_LINE_END_TYPE_UNICODE includes U+2028 Line Separator,
+# U+2029 Paragraph Separator, and U+0085 Next Line
+enu LineEndType=SC_LINE_END_TYPE_
+val SC_LINE_END_TYPE_DEFAULT=0
+val SC_LINE_END_TYPE_UNICODE=1
+
+# Set the line end types that the application wants to use. May not be used if incompatible with lexer or
encoding.
+set void SetLineEndTypesAllowed=2656(int lineEndBitSet,)
+
+# Get the line end types currently allowed.
+get int GetLineEndTypesAllowed=2657(,)
+
+# Get the line end types currently recognised. May be a subset of the allowed types due to lexer limitation.
+get int GetLineEndTypesActive=2658(,)
+
+# Bit set of LineEndType enumertion for which line ends beyond the standard
+# LF, CR, and CRLF are supported by the lexer.
+get int GetLineEndTypesSupported=4018(,)
+
+# Allocate a set of sub styles for a particular base style, returning start of range
+fun int AllocateSubStyles=4020(int styleBase, int numberStyles)
+
+# The starting style number for the sub styles associated with a base style
+get int GetSubStylesStart=4021(int styleBase,)
+
+# The number of sub styles associated with a base style
+get int GetSubStylesLength=4022(int styleBase,)
+
+# Free allocated sub styles
+fun void FreeSubStyles=4023(,)
+
+# Set the identifiers that are shown in a particular style
+set void SetIdentifiers=4024(int style, string identifiers)
+
+# Where styles are duplicated by a feature such as active/inactive code
+# return the distance between the two types.
+get int DistanceToSecondaryStyles=4025(,)
+
+# Get the set of base styles that can be extended with sub styles
+get int GetSubStyleBases=4026(, stringresult styles)
+
cat Deprecated
# Deprecated in 2.21
diff --git a/plugins/scintilla/scintilla/lexers.make b/plugins/scintilla/scintilla/lexers.make
index a703339..9e26f46 100644
--- a/plugins/scintilla/scintilla/lexers.make
+++ b/plugins/scintilla/scintilla/lexers.make
@@ -38,6 +38,7 @@ LEXER_OBJS = \
lexers/LexHTML.o\
lexers/LexInno.o\
lexers/LexKix.o\
+ lexers/LexLaTeX.o\
lexers/LexLisp.o\
lexers/LexLout.o\
lexers/LexLua.o\
@@ -59,6 +60,7 @@ LEXER_OBJS = \
lexers/LexPB.o\
lexers/LexPerl.o\
lexers/LexPLM.o\
+ lexers/LexPO.o\
lexers/LexPOV.o\
lexers/LexPowerPro.o\
lexers/LexPowerShell.o\
@@ -127,6 +129,7 @@ LEXER_SRCS = \
lexers/LexHTML.cxx\
lexers/LexInno.cxx\
lexers/LexKix.cxx\
+ lexers/LexLaTeX.cxx\
lexers/LexLisp.cxx\
lexers/LexLout.cxx\
lexers/LexLua.cxx\
@@ -148,6 +151,7 @@ LEXER_SRCS = \
lexers/LexPB.cxx\
lexers/LexPerl.cxx\
lexers/LexPLM.cxx\
+ lexers/LexPO.cxx\
lexers/LexPOV.cxx\
lexers/LexPowerPro.cxx\
lexers/LexPowerShell.cxx\
diff --git a/plugins/scintilla/scintilla/lexers/LexBash.cxx b/plugins/scintilla/scintilla/lexers/LexBash.cxx
index 8cd6cc5..2dc8707 100644
--- a/plugins/scintilla/scintilla/lexers/LexBash.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexBash.cxx
@@ -2,7 +2,7 @@
/** @file LexBash.cxx
** Lexer for Bash.
**/
-// Copyright 2004-2010 by Neil Hodgson <neilh scintilla org>
+// Copyright 2004-2012 by Neil Hodgson <neilh scintilla org>
// Adapted from LexPerl by Kein-Hong Man 2004
// The License.txt file describes the conditions under which this software may be distributed.
@@ -49,6 +49,17 @@ using namespace Scintilla;
#define BASH_CMD_ARITH 4
#define BASH_CMD_DELIM 5
+// state constants for nested delimiter pairs, used by
+// SCE_SH_STRING and SCE_SH_BACKTICKS processing
+#define BASH_DELIM_LITERAL 0
+#define BASH_DELIM_STRING 1
+#define BASH_DELIM_CSTRING 2
+#define BASH_DELIM_LSTRING 3
+#define BASH_DELIM_COMMAND 4
+#define BASH_DELIM_BACKTICK 5
+
+#define BASH_DELIM_STACK_MAX 7
+
static inline int translateBashDigit(int ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
@@ -154,6 +165,60 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
};
QuoteCls Quote;
+ class QuoteStackCls { // Class to manage quote pairs that nest
+ public:
+ int Count;
+ int Up, Down;
+ int Style;
+ int Depth; // levels pushed
+ int *CountStack;
+ int *UpStack;
+ int *StyleStack;
+ QuoteStackCls() {
+ Count = 0;
+ Up = '\0';
+ Down = '\0';
+ Style = 0;
+ Depth = 0;
+ CountStack = new int[BASH_DELIM_STACK_MAX];
+ UpStack = new int[BASH_DELIM_STACK_MAX];
+ StyleStack = new int[BASH_DELIM_STACK_MAX];
+ }
+ void Start(int u, int s) {
+ Count = 1;
+ Up = u;
+ Down = opposite(Up);
+ Style = s;
+ }
+ void Push(int u, int s) {
+ if (Depth >= BASH_DELIM_STACK_MAX)
+ return;
+ CountStack[Depth] = Count;
+ UpStack [Depth] = Up;
+ StyleStack[Depth] = Style;
+ Depth++;
+ Count = 1;
+ Up = u;
+ Down = opposite(Up);
+ Style = s;
+ }
+ void Pop(void) {
+ if (Depth <= 0)
+ return;
+ Depth--;
+ Count = CountStack[Depth];
+ Up = UpStack [Depth];
+ Style = StyleStack[Depth];
+ Down = opposite(Up);
+ }
+ ~QuoteStackCls() {
+ delete []CountStack;
+ delete []UpStack;
+ delete []StyleStack;
+ }
+ };
+ QuoteStackCls QuoteStack;
+
int numBase = 0;
int digit;
unsigned int endPos = startPos + length;
@@ -163,6 +228,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
// Always backtracks to the start of a line that is not a continuation
// of the previous line (i.e. start of a bash command segment)
int ln = styler.GetLine(startPos);
+ if (ln > 0 && startPos == static_cast<unsigned int>(styler.LineStart(ln)))
+ ln--;
for (;;) {
startPos = styler.LineStart(ln);
if (ln == 0 || styler.GetLineState(ln) == BASH_CMD_START)
@@ -376,7 +443,7 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.ForwardSetState(SCE_SH_DEFAULT);
} else if (sc.ch == '\\') {
// skip escape prefix
- } else {
+ } else if (!HereDoc.Quoted) {
sc.SetState(SCE_SH_DEFAULT);
}
if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force
blowup
@@ -401,8 +468,11 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
}
char s[HERE_DELIM_MAX];
sc.GetCurrent(s, sizeof(s));
- if (sc.LengthCurrent() == 0)
+ if (sc.LengthCurrent() == 0) { // '' or "" delimiters
+ if (prefixws == 0 && HereDoc.Quoted &&
HereDoc.DelimiterLength == 0)
+ sc.SetState(SCE_SH_DEFAULT);
break;
+ }
if (s[strlen(s) - 1] == '\r')
s[strlen(s) - 1] = '\0';
if (strcmp(HereDoc.Delimiter, s) == 0) {
@@ -424,9 +494,56 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
}
}
break;
- case SCE_SH_STRING: // delimited styles
+ case SCE_SH_STRING: // delimited styles, can nest
case SCE_SH_BACKTICKS:
- case SCE_SH_PARAM:
+ if (sc.ch == '\\' && QuoteStack.Up != '\\') {
+ if (QuoteStack.Style != BASH_DELIM_LITERAL)
+ sc.Forward();
+ } else if (sc.ch == QuoteStack.Down) {
+ QuoteStack.Count--;
+ if (QuoteStack.Count == 0) {
+ if (QuoteStack.Depth > 0) {
+ QuoteStack.Pop();
+ } else
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ }
+ } else if (sc.ch == QuoteStack.Up) {
+ QuoteStack.Count++;
+ } else {
+ if (QuoteStack.Style == BASH_DELIM_STRING ||
+ QuoteStack.Style == BASH_DELIM_LSTRING
+ ) { // do nesting for "string", $"locale-string"
+ if (sc.ch == '`') {
+ QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK);
+ } else if (sc.ch == '$' && sc.chNext == '(') {
+ sc.Forward();
+ QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND);
+ }
+ } else if (QuoteStack.Style == BASH_DELIM_COMMAND ||
+ QuoteStack.Style == BASH_DELIM_BACKTICK
+ ) { // do nesting for $(command), `command`
+ if (sc.ch == '\'') {
+ QuoteStack.Push(sc.ch, BASH_DELIM_LITERAL);
+ } else if (sc.ch == '\"') {
+ QuoteStack.Push(sc.ch, BASH_DELIM_STRING);
+ } else if (sc.ch == '`') {
+ QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK);
+ } else if (sc.ch == '$') {
+ if (sc.chNext == '\'') {
+ sc.Forward();
+ QuoteStack.Push(sc.ch, BASH_DELIM_CSTRING);
+ } else if (sc.chNext == '\"') {
+ sc.Forward();
+ QuoteStack.Push(sc.ch, BASH_DELIM_LSTRING);
+ } else if (sc.chNext == '(') {
+ sc.Forward();
+ QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND);
+ }
+ }
+ }
+ }
+ break;
+ case SCE_SH_PARAM: // ${parameter}
if (sc.ch == '\\' && Quote.Up != '\\') {
sc.Forward();
} else if (sc.ch == Quote.Down) {
@@ -461,8 +578,14 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.ChangeState(SCE_SH_ERROR);
}
// HereDoc.Quote always == '\''
+ sc.SetState(SCE_SH_HERE_Q);
+ } else if (HereDoc.DelimiterLength == 0) {
+ // no delimiter, illegal (but '' and "" are legal)
+ sc.ChangeState(SCE_SH_ERROR);
+ sc.SetState(SCE_SH_DEFAULT);
+ } else {
+ sc.SetState(SCE_SH_HERE_Q);
}
- sc.SetState(SCE_SH_HERE_Q);
}
// update cmdState about the current command segment
@@ -497,13 +620,13 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_SH_COMMENTLINE);
} else if (sc.ch == '\"') {
sc.SetState(SCE_SH_STRING);
- Quote.Start(sc.ch);
+ QuoteStack.Start(sc.ch, BASH_DELIM_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_SH_CHARACTER);
Quote.Start(sc.ch);
} else if (sc.ch == '`') {
sc.SetState(SCE_SH_BACKTICKS);
- Quote.Start(sc.ch);
+ QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK);
} else if (sc.ch == '$') {
if (sc.Match("$((")) {
sc.SetState(SCE_SH_OPERATOR); // handle '((' later
@@ -513,17 +636,22 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.Forward();
if (sc.ch == '{') {
sc.ChangeState(SCE_SH_PARAM);
+ Quote.Start(sc.ch);
} else if (sc.ch == '\'') {
sc.ChangeState(SCE_SH_STRING);
+ QuoteStack.Start(sc.ch, BASH_DELIM_CSTRING);
} else if (sc.ch == '"') {
sc.ChangeState(SCE_SH_STRING);
- } else if (sc.ch == '(' || sc.ch == '`') {
+ QuoteStack.Start(sc.ch, BASH_DELIM_LSTRING);
+ } else if (sc.ch == '(') {
+ sc.ChangeState(SCE_SH_BACKTICKS);
+ QuoteStack.Start(sc.ch, BASH_DELIM_COMMAND);
+ } else if (sc.ch == '`') { // $` seen in a configure script, valid?
sc.ChangeState(SCE_SH_BACKTICKS);
+ QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK);
} else {
continue; // scalar has no delimiter pair
}
- // fallthrough, open delim for $[{'"(`]
- Quote.Start(sc.ch);
} else if (sc.Match('<', '<')) {
sc.SetState(SCE_SH_HERE_DELIM);
HereDoc.State = 0;
@@ -597,6 +725,10 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
}// sc.state
}
sc.Complete();
+ if (sc.state == SCE_SH_HERE_Q) {
+ styler.ChangeLexerState(sc.currentPos, styler.Length());
+ }
+ sc.Complete();
}
static bool IsCommentLine(int line, Accessor &styler) {
@@ -651,7 +783,7 @@ static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
if (ch == '<' && chNext == '<') {
levelCurrent++;
}
- } else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_PL_DEFAULT) {
+ } else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_SH_DEFAULT) {
levelCurrent--;
}
if (atEOL) {
diff --git a/plugins/scintilla/scintilla/lexers/LexCPP.cxx b/plugins/scintilla/scintilla/lexers/LexCPP.cxx
index 7d0990f..116ea72 100644
--- a/plugins/scintilla/scintilla/lexers/LexCPP.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexCPP.cxx
@@ -30,6 +30,7 @@
#include "LexerModule.h"
#include "OptionSet.h"
#include "SparseState.h"
+#include "SubStyles.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -87,11 +88,15 @@ static std::string GetRestOfLine(LexAccessor &styler, int start, bool allowSpace
std::string restOfLine;
int i =0;
char ch = styler.SafeGetCharAt(start, '\n');
- while ((ch != '\r') && (ch != '\n')) {
+ int endLine = styler.LineEnd(styler.GetLine(start));
+ while (((start+i) < endLine) && (ch != '\r')) {
+ char chNext = styler.SafeGetCharAt(start + i + 1, '\n');
+ if (ch == '/' && (chNext == '/' || chNext == '*'))
+ break;
if (allowSpace || (ch != ' '))
restOfLine += ch;
i++;
- ch = styler.SafeGetCharAt(start + i, '\n');
+ ch = chNext;
}
return restOfLine;
}
@@ -127,8 +132,9 @@ struct PPDefinition {
int line;
std::string key;
std::string value;
- PPDefinition(int line_, const std::string &key_, const std::string &value_) :
- line(line_), key(key_), value(value_) {
+ bool isUndef;
+ PPDefinition(int line_, const std::string &key_, const std::string &value_, bool isUndef_ = false) :
+ line(line_), key(key_), value(value_), isUndef(isUndef_) {
}
};
@@ -307,7 +313,9 @@ struct OptionSetCPP : public OptionSet<OptionsCPP> {
}
};
-class LexerCPP : public ILexer {
+static const char styleSubable[] = {SCE_C_IDENTIFIER, SCE_C_COMMENTDOCKEYWORD, 0};
+
+class LexerCPP : public ILexerWithSubStyles {
bool caseSensitive;
CharacterSet setWord;
CharacterSet setNegationOp;
@@ -326,6 +334,8 @@ class LexerCPP : public ILexer {
OptionSetCPP osCPP;
SparseState<std::string> rawStringTerminators;
enum { activeFlag = 0x40 };
+ enum { ssIdentifier, ssDocKeyword };
+ SubStyles subStyles;
public:
LexerCPP(bool caseSensitive_) :
caseSensitive(caseSensitive_),
@@ -333,7 +343,8 @@ public:
setNegationOp(CharacterSet::setNone, "!"),
setArithmethicOp(CharacterSet::setNone, "+-/*%"),
setRelOp(CharacterSet::setNone, "=!<>"),
- setLogicalOp(CharacterSet::setNone, "|&") {
+ setLogicalOp(CharacterSet::setNone, "|&"),
+ subStyles(styleSubable, 0x80, 0x40, activeFlag) {
}
virtual ~LexerCPP() {
}
@@ -341,7 +352,7 @@ public:
delete this;
}
int SCI_METHOD Version() const {
- return lvOriginal;
+ return lvSubStyles;
}
const char * SCI_METHOD PropertyNames() {
return osCPP.PropertyNames();
@@ -364,6 +375,32 @@ public:
return 0;
}
+ int SCI_METHOD LineEndTypesSupported() {
+ return SC_LINE_END_TYPE_UNICODE;
+ };
+
+ int SCI_METHOD AllocateSubStyles(int styleBase, int numberStyles) {
+ return subStyles.Allocate(styleBase, numberStyles);
+ }
+ int SCI_METHOD SubStylesStart(int styleBase) {
+ return subStyles.Start(styleBase);
+ }
+ int SCI_METHOD SubStylesLength(int styleBase) {
+ return subStyles.Length(styleBase);
+ }
+ void SCI_METHOD FreeSubStyles() {
+ subStyles.Free();
+ }
+ void SCI_METHOD SetIdentifiers(int style, const char *identifiers) {
+ subStyles.SetIdentifiers(style, identifiers);
+ }
+ int SCI_METHOD DistanceToSecondaryStyles() {
+ return activeFlag;
+ }
+ const char * SCI_METHOD GetSubStyleBases() {
+ return styleSubable;
+ }
+
static ILexer *LexerFactoryCPP() {
return new LexerCPP(true);
}
@@ -379,6 +416,12 @@ public:
int SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) {
if (osCPP.PropertySet(&options, key, val)) {
+ if (strcmp(key, "lexer.cpp.allow.dollars") == 0) {
+ setWord = CharacterSet(CharacterSet::setAlphaNum, "._", 0x80, true);
+ if (options.identifiersAllowDollars) {
+ setWord.Add('$');
+ }
+ }
return 0;
}
return -1;
@@ -451,9 +494,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
+ CharacterSet setInvalidRawFirst(CharacterSet::setNone, " )\\\t\v\f\n");
+
if (options.identifiersAllowDollars) {
setWordStart.Add('$');
- setWord.Add('$');
}
int chPrevNonWhite = ' ';
@@ -462,6 +506,8 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
int styleBeforeDCKeyword = SCE_C_DEFAULT;
bool continuationLine = false;
bool isIncludePreprocessor = false;
+ bool isStringInPreprocessor = false;
+ bool inRERange = false;
int lineCurrent = styler.GetLine(startPos);
if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) ||
@@ -469,15 +515,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
(MaskActive(initStyle) == SCE_C_COMMENTLINEDOC)) {
// Set continuationLine if last character of previous line is '\'
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;
+ int endLinePrevious = styler.LineEnd(lineCurrent - 1);
+ if (endLinePrevious > 0) {
+ continuationLine = styler.SafeGetCharAt(endLinePrevious-1) == '\\';
}
- continuationLine = lineEndChar == '\\';
}
}
@@ -491,7 +532,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
}
- StyleContext sc(startPos, length, initStyle, styler, 0x7f);
+ StyleContext sc(startPos, length, initStyle, styler, static_cast<char>(0xff));
LinePPState preproc = vlls.ForLine(lineCurrent);
bool definitionsChanged = false;
@@ -509,7 +550,10 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
std::map<std::string, std::string> preprocessorDefinitions = preprocessorDefinitionsStart;
for (std::vector<PPDefinition>::iterator itDef = ppDefineHistory.begin(); itDef !=
ppDefineHistory.end(); ++itDef) {
- preprocessorDefinitions[itDef->key] = itDef->value;
+ if (itDef->isUndef)
+ preprocessorDefinitions.erase(itDef->key);
+ else
+ preprocessorDefinitions[itDef->key] = itDef->value;
}
std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
@@ -517,7 +561,12 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
int activitySet = preproc.IsInactive() ? activeFlag : 0;
- for (; sc.More(); sc.Forward()) {
+ const WordClassifier &classifierIdentifiers = subStyles.Classifier(SCE_C_IDENTIFIER);
+ const WordClassifier &classifierDocKeyWords = subStyles.Classifier(SCE_C_COMMENTDOCKEYWORD);
+
+ int lineEndNext = styler.LineEnd(lineCurrent);
+
+ for (; sc.More();) {
if (sc.atLineStart) {
// Using MaskActive() is not needed in the following statement.
@@ -527,11 +576,15 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
// ends with a line continuation by locking in the state upto this position.
sc.SetState(sc.state);
}
+ if ((MaskActive(sc.state) == SCE_C_PREPROCESSOR) && (!continuationLine)) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
// Reset states to begining of colourise so no surprises
// if different sets of lines lexed.
visibleChars = 0;
lastWordWasUUID = false;
isIncludePreprocessor = false;
+ inRERange = false;
if (preproc.IsInactive()) {
activitySet = activeFlag;
sc.SetState(sc.state | activitySet);
@@ -540,6 +593,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
if (sc.atLineEnd) {
lineCurrent++;
+ lineEndNext = styler.LineEnd(lineCurrent);
vlls.Add(lineCurrent, preproc);
if (rawStringTerminator != "") {
rawSTNew.Set(lineCurrent-1, rawStringTerminator);
@@ -548,14 +602,17 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
// Handle line continuation generically.
if (sc.ch == '\\') {
- if (sc.chNext == '\n' || sc.chNext == '\r') {
+ if (static_cast<int>((sc.currentPos+1)) >= lineEndNext) {
lineCurrent++;
+ lineEndNext = styler.LineEnd(lineCurrent);
vlls.Add(lineCurrent, preproc);
sc.Forward();
if (sc.ch == '\r' && sc.chNext == '\n') {
+ // Even in UTF-8, \r and \n are separate
sc.Forward();
}
continuationLine = true;
+ sc.Forward();
continue;
}
}
@@ -569,12 +626,14 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
break;
case SCE_C_NUMBER:
// We accept almost anything because of hex. and number suffixes
- if (!(setWord.Contains(sc.ch) || ((sc.ch == '+' || sc.ch == '-') &&
(sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+ if (!(setWord.Contains(sc.ch)
+ || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev ==
'E' ||
+ sc.chPrev == 'p' || sc.chPrev ==
'P')))) {
sc.SetState(SCE_C_DEFAULT|activitySet);
}
break;
case SCE_C_IDENTIFIER:
- if (!setWord.Contains(sc.ch) || (sc.ch == '.')) {
+ if (sc.atLineStart || sc.atLineEnd || !setWord.Contains(sc.ch) || (sc.ch ==
'.')) {
char s[1000];
if (caseSensitive) {
sc.GetCurrent(s, sizeof(s));
@@ -588,11 +647,16 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.ChangeState(SCE_C_WORD2|activitySet);
} else if (keywords4.InList(s)) {
sc.ChangeState(SCE_C_GLOBALCLASS|activitySet);
+ } else {
+ int subStyle = classifierIdentifiers.ValueFor(s);
+ if (subStyle >= 0) {
+ sc.ChangeState(subStyle|activitySet);
+ }
}
const bool literalString = sc.ch == '\"';
if (literalString || sc.ch == '\'') {
size_t lenS = strlen(s);
- const bool raw = literalString && sc.chPrev == 'R';
+ const bool raw = literalString && sc.chPrev == 'R' &&
!setInvalidRawFirst.Contains(sc.chNext);
if (raw)
s[lenS--] = '\0';
bool valid =
@@ -609,19 +673,31 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_C_DEFAULT|activitySet);
}
break;
- case SCE_C_PREPROCESSOR:
- if (sc.atLineStart && !continuationLine) {
- sc.SetState(SCE_C_DEFAULT|activitySet);
- } else if (options.stylingWithinPreprocessor) {
+ case SCE_C_PREPROCESSOR:
+ if (options.stylingWithinPreprocessor) {
if (IsASpace(sc.ch)) {
sc.SetState(SCE_C_DEFAULT|activitySet);
}
- } else {
- if (sc.Match('/', '*') || sc.Match('/', '/')) {
+ } else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"'))) {
+ isStringInPreprocessor = false;
+ } else if (!isStringInPreprocessor) {
+ if ((isIncludePreprocessor && sc.Match('<')) || sc.Match('\"')) {
+ isStringInPreprocessor = true;
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(SCE_C_PREPROCESSORCOMMENT|activitySet);
+ sc.Forward(); // Eat the *
+ } else if (sc.Match('/', '/')) {
sc.SetState(SCE_C_DEFAULT|activitySet);
}
}
break;
+ case SCE_C_PREPROCESSORCOMMENT:
+ if (sc.Match('*', '/')) {
+ sc.Forward();
+ sc.ForwardSetState(SCE_C_PREPROCESSOR|activitySet);
+ continue; // Without advancing in case of '\'.
+ }
+ break;
case SCE_C_COMMENT:
if (sc.Match('*', '/')) {
sc.Forward();
@@ -668,8 +744,15 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} else {
sc.GetCurrentLowered(s, sizeof(s));
}
- if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
+ if (!IsASpace(sc.ch)) {
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
+ } else if (!keywords3.InList(s + 1)) {
+ int subStyleCDKW = classifierDocKeyWords.ValueFor(s+1);
+ if (subStyleCDKW >= 0) {
+ sc.ChangeState(subStyleCDKW|activitySet);
+ } else {
+
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
+ }
}
sc.SetState(styleBeforeDCKeyword|activitySet);
}
@@ -721,16 +804,18 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
case SCE_C_REGEX:
if (sc.atLineStart) {
sc.SetState(SCE_C_DEFAULT|activitySet);
- } else if (sc.ch == '/') {
+ } else if (! inRERange && sc.ch == '/') {
sc.Forward();
while ((sc.ch < 0x80) && islower(sc.ch))
sc.Forward(); // gobble regex flags
sc.SetState(SCE_C_DEFAULT|activitySet);
- } else if (sc.ch == '\\') {
- // Gobble up the quoted character
- if (sc.chNext == '\\' || sc.chNext == '/') {
- sc.Forward();
- }
+ } else if (sc.ch == '\\' && (static_cast<int>(sc.currentPos+1) <
lineEndNext)) {
+ // Gobble up the escaped character
+ sc.Forward();
+ } else if (sc.ch == '[') {
+ inRERange = true;
+ } else if (sc.ch == ']') {
+ inRERange = false;
}
break;
case SCE_C_STRINGEOL:
@@ -756,7 +841,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
break;
case SCE_C_UUID:
- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
+ if (sc.atLineEnd || sc.ch == ')') {
sc.SetState(SCE_C_DEFAULT|activitySet);
}
}
@@ -764,6 +849,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
if (sc.atLineEnd && !atLineEndBeforeSwitch) {
// State exit processing consumed characters up to end of line.
lineCurrent++;
+ lineEndNext = styler.LineEnd(lineCurrent);
vlls.Add(lineCurrent, preproc);
}
@@ -785,7 +871,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
} else {
sc.SetState(SCE_C_NUMBER|activitySet);
}
- } else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
+ } else if (!sc.atLineEnd && (setWordStart.Contains(sc.ch) || (sc.ch == '@'))) {
if (lastWordWasUUID) {
sc.SetState(SCE_C_UUID|activitySet);
lastWordWasUUID = false;
@@ -811,6 +897,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
&& (!setCouldBePostOp.Contains(chPrevNonWhite)
|| !FollowsPostfixOperator(sc, styler))) {
sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx
+ inRERange = false;
} else if (sc.ch == '\"') {
if (sc.chPrev == 'R') {
styler.Flush();
@@ -910,19 +997,32 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
}
}
}
+ } else if (sc.Match("undef")) {
+ if (options.updatePreprocessor &&
!preproc.IsInactive()) {
+ std::string restOfLine =
GetRestOfLine(styler, sc.currentPos + 5, true);
+ std::vector<std::string> tokens =
Tokenize(restOfLine);
+ std::string key;
+ if (tokens.size() >= 1) {
+ key = tokens[0];
+ preprocessorDefinitions.erase(key);
+
ppDefineHistory.push_back(PPDefinition(lineCurrent, key, "", true));
+ definitionsChanged = true;
+ }
+ }
}
}
}
- } else if (isoperator(static_cast<char>(sc.ch))) {
+ } else if (isoperator(sc.ch)) {
sc.SetState(SCE_C_OPERATOR|activitySet);
}
}
- if (!IsASpace(sc.ch) && !IsSpaceEquiv(sc.state)) {
+ if (!IsASpace(sc.ch) && !IsSpaceEquiv(MaskActive(sc.state))) {
chPrevNonWhite = sc.ch;
visibleChars++;
}
continuationLine = false;
+ sc.Forward();
}
const bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent);
if (definitionsChanged || rawStringsChanged)
@@ -943,10 +1043,12 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
unsigned int endPos = startPos + length;
int visibleChars = 0;
+ bool inLineComment = false;
int lineCurrent = styler.GetLine(startPos);
int levelCurrent = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ unsigned int lineStartNext = styler.LineStart(lineCurrent+1);
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
@@ -959,11 +1061,13 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
int stylePrev = style;
style = styleNext;
styleNext = MaskActive(styler.StyleAt(i + 1));
- bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
- if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
+ bool atEOL = i == (lineStartNext-1);
+ if ((style == SCE_C_COMMENTLINE) || (style == SCE_C_COMMENTLINEDOC))
+ inLineComment = true;
+ if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style) &&
!inLineComment) {
+ if (!IsStreamCommentStyle(stylePrev)) {
levelNext++;
- } else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) &&
!atEOL) {
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
// Comments don't end at end of line and the next character may be unstyled.
levelNext--;
}
@@ -1027,6 +1131,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
styler.SetLevel(lineCurrent, lev);
}
lineCurrent++;
+ lineStartNext = styler.LineStart(lineCurrent+1);
levelCurrent = levelNext;
levelMinCurrent = levelCurrent;
if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
@@ -1034,6 +1139,7 @@ void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle,
styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) |
SC_FOLDLEVELWHITEFLAG);
}
visibleChars = 0;
+ inLineComment = false;
}
}
}
@@ -1147,7 +1253,7 @@ bool LexerCPP::EvaluateExpression(const std::string &expr, const std::map<std::s
std::vector<std::string> tokens;
const char *cp = expr.c_str();
for (;;) {
- if (setWord.Contains(*cp)) {
+ if (setWord.Contains(static_cast<unsigned char>(*cp))) {
word += *cp;
} else {
std::map<std::string, std::string>::const_iterator it =
preprocessorDefinitions.find(word);
@@ -1162,13 +1268,13 @@ bool LexerCPP::EvaluateExpression(const std::string &expr, const std::map<std::s
}
if ((*cp != ' ') && (*cp != '\t')) {
std::string op(cp, 1);
- if (setRelOp.Contains(*cp)) {
- if (setRelOp.Contains(cp[1])) {
+ if (setRelOp.Contains(static_cast<unsigned char>(*cp))) {
+ if (setRelOp.Contains(static_cast<unsigned char>(cp[1]))) {
op += cp[1];
cp++;
}
- } else if (setLogicalOp.Contains(*cp)) {
- if (setLogicalOp.Contains(cp[1])) {
+ } else if (setLogicalOp.Contains(static_cast<unsigned char>(*cp))) {
+ if (setLogicalOp.Contains(static_cast<unsigned char>(cp[1]))) {
op += cp[1];
cp++;
}
diff --git a/plugins/scintilla/scintilla/lexers/LexCSS.cxx b/plugins/scintilla/scintilla/lexers/LexCSS.cxx
index 305a1dd..036bb2e 100644
--- a/plugins/scintilla/scintilla/lexers/LexCSS.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexCSS.cxx
@@ -98,18 +98,29 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
// Set to 1 for Sassy CSS (.scss)
bool isScssDocument = styler.GetPropertyInt("lexer.css.scss.language") != 0;
- // TODO: implement Less support
- bool isLessDocument = false;
+ // property lexer.css.less.language
+ // Set to 1 for Less CSS (.less)
+ bool isLessDocument = styler.GetPropertyInt("lexer.css.less.language") != 0;
- // SCSS and Less both support single-line comments
+ // property lexer.css.hss.language
+ // Set to 1 for HSS (.hss)
+ bool isHssDocument = styler.GetPropertyInt("lexer.css.hss.language") != 0;
+
+ // SCSS/LESS/HSS have the concept of variable
+ bool hasVariables = isScssDocument || isLessDocument || isHssDocument;
+ char varPrefix = 0;
+ if (hasVariables)
+ varPrefix = isLessDocument ? '@' : '$';
+
+ // SCSS/LESS/HSS support single-line comments
typedef enum _CommentModes { eCommentBlock = 0, eCommentLine = 1} CommentMode;
CommentMode comment_mode = eCommentBlock;
- bool hasSingleLineComments = isScssDocument || isLessDocument;
+ bool hasSingleLineComments = isScssDocument || isLessDocument || isHssDocument;
- // must keep track of nesting level in document types that support it (SCSS, Less)
+ // must keep track of nesting level in document types that support it (SCSS/LESS/HSS)
bool hasNesting = false;
int nestingLevel = 0;
- if (isScssDocument || isLessDocument) {
+ if (isScssDocument || isLessDocument || isHssDocument) {
hasNesting = true;
nestingLevel = NestingLevelLookBehind(startPos, styler);
}
@@ -329,11 +340,13 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
insideParentheses = false;
// SCSS special modes
- if (isScssDocument) {
+ if (hasVariables) {
// variable name
- if (sc.ch == '$') {
+ if (sc.ch == varPrefix) {
switch (sc.state) {
case SCE_CSS_DEFAULT:
+ if (isLessDocument) // give priority to pseudo elements
+ break;
case SCE_CSS_VALUE:
lastStateVar = sc.state;
sc.SetState(SCE_CSS_VARIABLE);
diff --git a/plugins/scintilla/scintilla/lexers/LexFortran.cxx
b/plugins/scintilla/scintilla/lexers/LexFortran.cxx
index 6c61c54..bfbe301 100644
--- a/plugins/scintilla/scintilla/lexers/LexFortran.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexFortran.cxx
@@ -87,7 +87,7 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
/***********************************************/
// Handle the fix format generically
int toLineStart = sc.currentPos - posLineStart;
- if (isFixFormat && (toLineStart < 6 || toLineStart > 72)) {
+ if (isFixFormat && (toLineStart < 6 || toLineStart >= 72)) {
if ((toLineStart == 0 && (tolower(sc.ch) == 'c' || sc.ch == '*')) || sc.ch == '!') {
if (sc.MatchIgnoreCase("cdec$") || sc.MatchIgnoreCase("*dec$") ||
sc.MatchIgnoreCase("!dec$") ||
sc.MatchIgnoreCase("cdir$") || sc.MatchIgnoreCase("*dir$") ||
sc.MatchIgnoreCase("!dir$") ||
@@ -99,7 +99,7 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
}
while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
- } else if (toLineStart > 72) {
+ } else if (toLineStart >= 72) {
sc.SetState(SCE_F_COMMENT);
while (!sc.atLineEnd && sc.More()) sc.Forward(); // Until line end
} else if (toLineStart < 5) {
@@ -108,17 +108,27 @@ static void ColouriseFortranDoc(unsigned int startPos, int length, int initStyle
else
sc.SetState(SCE_F_DEFAULT);
} else if (toLineStart == 5) {
- if (!IsASpace(sc.ch) && sc.ch != '0') {
+ //if (!IsASpace(sc.ch) && sc.ch != '0') {
+ if (sc.ch != '\r' && sc.ch != '\n') {
sc.SetState(SCE_F_CONTINUATION);
- sc.ForwardSetState(prevState);
+ if (!IsASpace(sc.ch) && sc.ch != '0')
+ sc.ForwardSetState(prevState);
} else
sc.SetState(SCE_F_DEFAULT);
}
continue;
}
/***************************************/
+ // Hanndle preprocessor directives
+ if (sc.ch == '#' && numNonBlank == 1)
+ {
+ sc.SetState(SCE_F_PREPROCESSOR);
+ while (!sc.atLineEnd && sc.More())
+ sc.Forward(); // Until line end
+ }
+ /***************************************/
// Handle line continuation generically.
- if (!isFixFormat && sc.ch == '&') {
+ if (!isFixFormat && sc.ch == '&' && sc.state != SCE_F_COMMENT) {
char chTemp = ' ';
int j = 1;
while (IsABlank(chTemp) && j<132) {
@@ -252,7 +262,8 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
|| strcmp(s, "function") == 0 || strcmp(s, "interface") == 0
|| strcmp(s, "module") == 0 || strcmp(s, "program") == 0
|| strcmp(s, "subroutine") == 0 || strcmp(s, "then") == 0
- || (strcmp(s, "type") == 0 && chNextNonBlank != '(') ){
+ || (strcmp(s, "type") == 0 && chNextNonBlank != '(')
+ || strcmp(s, "critical") == 0){
if (strcmp(prevWord, "end") == 0)
lev = 0;
else
@@ -265,12 +276,14 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
|| strcmp(s, "endfunction") == 0 || strcmp(s, "endinterface") == 0
|| strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
- || strcmp(s, "endwhere") == 0
- || (strcmp(s, "procedure") == 0 && strcmp(prevWord,"module")==0) ) { // Take care of the
module procedure statement
+ || strcmp(s, "endwhere") == 0 || strcmp(s, "endcritical") == 0
+ || (strcmp(s, "procedure") == 0 && strcmp(prevWord, "module") == 0) ) { // Take care of the
"module procedure" statement
lev = -1;
} else if (strcmp(prevWord, "end") == 0 && strcmp(s, "if") == 0){ // end if
lev = 0;
- }
+ } else if (strcmp(prevWord, "type") == 0 && strcmp(s, "is") == 0){ // type is
+ lev = -1;
+ }
return lev;
}
// Folding the code
@@ -312,7 +325,7 @@ static void FoldFortranDoc(unsigned int startPos, int length, int initStyle,
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
//
- if (stylePrev == SCE_F_DEFAULT && (style == SCE_F_WORD || style == SCE_F_LABEL)) {
+ if (((isFixFormat && stylePrev == SCE_F_CONTINUATION) || stylePrev == SCE_F_DEFAULT ||
stylePrev == SCE_F_OPERATOR) && (style == SCE_F_WORD || style == SCE_F_LABEL)) {
// Store last word and label start point.
lastStart = i;
}
diff --git a/plugins/scintilla/scintilla/lexers/LexHTML.cxx b/plugins/scintilla/scintilla/lexers/LexHTML.cxx
index 372a5b7..ebfd730 100644
--- a/plugins/scintilla/scintilla/lexers/LexHTML.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexHTML.cxx
@@ -297,7 +297,7 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
if (allowScripts && 0 == strcmp(s, "script")) {
// check to see if this is a self-closing tag by sniffing ahead
bool isSelfClose = false;
- for (unsigned int cPos = end; cPos <= end + 100; cPos++) {
+ for (unsigned int cPos = end; cPos <= end + 200; cPos++) {
char ch = styler.SafeGetCharAt(cPos, '\0');
if (ch == '\0' || ch == '>')
break;
@@ -445,11 +445,6 @@ static int StateForScript(script_type scriptLanguage) {
return Result;
}
-static inline bool ishtmlwordchar(int ch) {
- return !isascii(ch) ||
- (isalnum(ch) || ch == '.' || ch == '-' || ch == '_' || ch == ':' || ch == '!' || ch == '#');
-}
-
static inline bool issgmlwordchar(int ch) {
return !isascii(ch) ||
(isalnum(ch) || ch == '.' || ch == '_' || ch == ':' || ch == '!' || ch == '#' || ch == '[');
@@ -484,10 +479,6 @@ static bool isLineEnd(int ch) {
return ch == '\r' || ch == '\n';
}
-static bool isOKBeforeRE(int ch) {
- return (ch == '(') || (ch == '=') || (ch == ',');
-}
-
static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType) {
if (strlen(blockType) == 0) {
return ((ch == '%') && (chNext == '>'));
@@ -691,6 +682,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
+ // TODO: also handle + and - (except if they're part of ++ or --) and return keywords
+ const CharacterSet setOKBeforeJSRE(CharacterSet::setNone, "([{=,:;!%^&*|?~");
int levelPrev = styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent = levelPrev;
@@ -905,7 +898,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
!IsScriptCommentState(state)) {
beforeLanguage = scriptLanguage;
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, isXml ? eScriptXML :
eScriptPHP);
- if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
+ if ((scriptLanguage != eScriptPHP) && (isStringState(state) ||
(state==SCE_H_COMMENT))) continue;
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
i++;
@@ -1089,7 +1082,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
state = SCE_H_SGML_COMMAND; // wait for a pending command
}
// fold whole tag (-- when closing the tag)
- if (foldHTMLPreprocessor || (state == SCE_H_COMMENT))
+ if (foldHTMLPreprocessor || state == SCE_H_COMMENT || state == SCE_H_CDATA)
levelCurrent++;
continue;
}
@@ -1592,7 +1585,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
} else if (ch == '/' && chNext == '/') {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_COMMENTLINE;
- } else if (ch == '/' && isOKBeforeRE(chPrevNonWhite)) {
+ } else if (ch == '/' && setOKBeforeJSRE.Contains(chPrevNonWhite)) {
styler.ColourTo(i - 1, StateToPrint);
state = SCE_HJ_REGEX;
} else if (ch == '\"') {
diff --git a/plugins/scintilla/scintilla/lexers/LexLaTeX.cxx b/plugins/scintilla/scintilla/lexers/LexLaTeX.cxx
new file mode 100644
index 0000000..6f9612d
--- /dev/null
+++ b/plugins/scintilla/scintilla/lexers/LexLaTeX.cxx
@@ -0,0 +1,539 @@
+// Scintilla source code edit control
+/** @file LexLaTeX.cxx
+ ** Lexer for LaTeX2e.
+ **/
+// Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// Modified by G. HU in 2013. Added folding, syntax highting inside math environments, and changed some
minor behaviors.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+#include <vector>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+using namespace std;
+
+struct latexFoldSave {
+ latexFoldSave() : structLev(0) {
+ for (int i = 0; i < 8; ++i) openBegins[i] = 0;
+ }
+ latexFoldSave(const latexFoldSave &save) : structLev(save.structLev) {
+ for (int i = 0; i < 8; ++i) openBegins[i] = save.openBegins[i];
+ }
+ int openBegins[8];
+ int structLev;
+};
+
+class LexerLaTeX : public LexerBase {
+private:
+ vector<int> modes;
+ void setMode(int line, int mode) {
+ if (line >= static_cast<int>(modes.size())) modes.resize(line + 1, 0);
+ modes[line] = mode;
+ }
+ int getMode(int line) {
+ if (line >= 0 && line < static_cast<int>(modes.size())) return modes[line];
+ return 0;
+ }
+ void truncModes(int numLines) {
+ if (static_cast<int>(modes.size()) > numLines * 2 + 256)
+ modes.resize(numLines + 128);
+ }
+
+ vector<latexFoldSave> saves;
+ void setSave(int line, const latexFoldSave &save) {
+ if (line >= static_cast<int>(saves.size())) saves.resize(line + 1);
+ saves[line] = save;
+ }
+ void getSave(int line, latexFoldSave &save) {
+ if (line >= 0 && line < static_cast<int>(saves.size())) save = saves[line];
+ else {
+ save.structLev = 0;
+ for (int i = 0; i < 8; ++i) save.openBegins[i] = 0;
+ }
+ }
+ void truncSaves(int numLines) {
+ if (static_cast<int>(saves.size()) > numLines * 2 + 256)
+ saves.resize(numLines + 128);
+ }
+public:
+ static ILexer *LexerFactoryLaTeX() {
+ return new LexerLaTeX();
+ }
+ void SCI_METHOD Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess);
+};
+
+static bool latexIsSpecial(int ch) {
+ return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
+ (ch == '{') || (ch == '}') || (ch == ' ');
+}
+
+static bool latexIsBlank(int ch) {
+ return (ch == ' ') || (ch == '\t');
+}
+
+static bool latexIsBlankAndNL(int ch) {
+ return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
+}
+
+static bool latexIsLetter(int ch) {
+ return isascii(ch) && isalpha(ch);
+}
+
+static bool latexIsTagValid(int &i, int l, Accessor &styler) {
+ while (i < l) {
+ if (styler.SafeGetCharAt(i) == '{') {
+ while (i < l) {
+ i++;
+ if (styler.SafeGetCharAt(i) == '}') {
+ return true;
+ } else if (!latexIsLetter(styler.SafeGetCharAt(i)) &&
+ styler.SafeGetCharAt(i)!='*') {
+ return false;
+ }
+ }
+ } else if (!latexIsBlank(styler.SafeGetCharAt(i))) {
+ return false;
+ }
+ i++;
+ }
+ return false;
+}
+
+static bool latexNextNotBlankIs(int i, Accessor &styler, char needle) {
+ char ch;
+ while (i < styler.Length()) {
+ ch = styler.SafeGetCharAt(i);
+ if (!latexIsBlankAndNL(ch) && ch != '*') {
+ if (ch == needle)
+ return true;
+ else
+ return false;
+ }
+ i++;
+ }
+ return false;
+}
+
+static bool latexLastWordIs(int start, Accessor &styler, const char *needle) {
+ unsigned int i = 0;
+ unsigned int l = static_cast<unsigned int>(strlen(needle));
+ int ini = start-l+1;
+ char s[32];
+
+ while (i < l && i < 31) {
+ s[i] = styler.SafeGetCharAt(ini + i);
+ i++;
+ }
+ s[i] = '\0';
+
+ return (strcmp(s, needle) == 0);
+}
+
+static bool latexLastWordIsMathEnv(int pos, Accessor &styler) {
+ int i, j;
+ char s[32];
+ const char *mathEnvs[] = { "align", "alignat", "flalign", "gather",
+ "multiline", "displaymath", "eqnarray", "equation" };
+ if (styler.SafeGetCharAt(pos) != '}') return false;
+ for (i = pos - 1; i >= 0; --i) {
+ if (styler.SafeGetCharAt(i) == '{') break;
+ if (pos - i >= 20) return false;
+ }
+ if (i < 0 || i == pos - 1) return false;
+ ++i;
+ for (j = 0; i + j < pos; ++j)
+ s[j] = styler.SafeGetCharAt(i + j);
+ s[j] = '\0';
+ if (j == 0) return false;
+ if (s[j - 1] == '*') s[--j] = '\0';
+ for (i = 0; i < static_cast<int>(sizeof(mathEnvs) / sizeof(const char *)); ++i)
+ if (strcmp(s, mathEnvs[i]) == 0) return true;
+ return false;
+}
+
+static inline void latexStateReset(int &mode, int &state) {
+ switch (mode) {
+ case 1: state = SCE_L_MATH; break;
+ case 2: state = SCE_L_MATH2; break;
+ default: state = SCE_L_DEFAULT; break;
+ }
+}
+
+// There are cases not handled correctly, like $abcd\textrm{what is $x+y$}z+w$.
+// But I think it's already good enough.
+void SCI_METHOD LexerLaTeX::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ // startPos is assumed to be the first character of a line
+ Accessor styler(pAccess, &props);
+ styler.StartAt(startPos);
+ int mode = getMode(styler.GetLine(startPos) - 1);
+ int state = initStyle;
+ if (state == SCE_L_ERROR || state == SCE_L_SHORTCMD || state == SCE_L_SPECIAL) // should not happen
+ latexStateReset(mode, state);
+
+ char chNext = styler.SafeGetCharAt(startPos);
+ char chVerbatimDelim = '\0';
+ styler.StartSegment(startPos);
+ int lengthDoc = startPos + length;
+
+ for (int i = startPos; i < lengthDoc; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+
+ if (styler.IsLeadByte(ch)) {
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ continue;
+ }
+
+ if (ch == '\r' || ch == '\n')
+ setMode(styler.GetLine(i), mode);
+
+ switch (state) {
+ case SCE_L_DEFAULT :
+ switch (ch) {
+ case '\\' :
+ styler.ColourTo(i - 1, state);
+ if (latexIsLetter(chNext)) {
+ state = SCE_L_COMMAND;
+ } else if (latexIsSpecial(chNext)) {
+ styler.ColourTo(i + 1, SCE_L_SPECIAL);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chNext == '\r' || chNext == '\n') {
+ styler.ColourTo(i, SCE_L_ERROR);
+ } else {
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ if (chNext == '(') {
+ mode = 1;
+ state = SCE_L_MATH;
+ } else if (chNext == '[') {
+ mode = 2;
+ state = SCE_L_MATH2;
+ }
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ break;
+ case '$' :
+ styler.ColourTo(i - 1, state);
+ if (chNext == '$') {
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ mode = 2;
+ state = SCE_L_MATH2;
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else {
+ styler.ColourTo(i, SCE_L_SHORTCMD);
+ mode = 1;
+ state = SCE_L_MATH;
+ }
+ break;
+ case '%' :
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMENT;
+ break;
+ }
+ break;
+ // These 3 will never be reached.
+ case SCE_L_ERROR:
+ case SCE_L_SPECIAL:
+ case SCE_L_SHORTCMD:
+ break;
+ case SCE_L_COMMAND :
+ if (!latexIsLetter(chNext)) {
+ styler.ColourTo(i, state);
+ if (latexNextNotBlankIs(i + 1, styler, '[' )) {
+ state = SCE_L_CMDOPT;
+ } else if (latexLastWordIs(i, styler, "\\begin")) {
+ state = SCE_L_TAG;
+ } else if (latexLastWordIs(i, styler, "\\end")) {
+ state = SCE_L_TAG2;
+ } else if (latexLastWordIs(i, styler, "\\verb") && chNext != '*' && chNext !=
' ') {
+ chVerbatimDelim = chNext;
+ state = SCE_L_VERBATIM;
+ } else {
+ latexStateReset(mode, state);
+ }
+ }
+ break;
+ case SCE_L_CMDOPT :
+ if (ch == ']') {
+ styler.ColourTo(i, state);
+ latexStateReset(mode, state);
+ }
+ break;
+ case SCE_L_TAG :
+ if (latexIsTagValid(i, lengthDoc, styler)) {
+ styler.ColourTo(i, state);
+ latexStateReset(mode, state);
+ if (latexLastWordIs(i, styler, "{verbatim}")) {
+ state = SCE_L_VERBATIM;
+ } else if (latexLastWordIs(i, styler, "{comment}")) {
+ state = SCE_L_COMMENT2;
+ } else if (latexLastWordIs(i, styler, "{math}") && mode == 0) {
+ mode = 1;
+ state = SCE_L_MATH;
+ } else if (latexLastWordIsMathEnv(i, styler) && mode == 0) {
+ mode = 2;
+ state = SCE_L_MATH2;
+ }
+ } else {
+ styler.ColourTo(i, SCE_L_ERROR);
+ latexStateReset(mode, state);
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode);
+ }
+ chNext = styler.SafeGetCharAt(i+1);
+ break;
+ case SCE_L_TAG2 :
+ if (latexIsTagValid(i, lengthDoc, styler)) {
+ styler.ColourTo(i, state);
+ latexStateReset(mode, state);
+ } else {
+ styler.ColourTo(i, SCE_L_ERROR);
+ latexStateReset(mode, state);
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '\r' || ch == '\n') setMode(styler.GetLine(i), mode);
+ }
+ chNext = styler.SafeGetCharAt(i+1);
+ break;
+ case SCE_L_MATH :
+ switch (ch) {
+ case '\\' :
+ styler.ColourTo(i - 1, state);
+ if (latexIsLetter(chNext)) {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{math}"))
+ mode = 0;
+ }
+ }
+ state = SCE_L_COMMAND;
+ } else if (latexIsSpecial(chNext)) {
+ styler.ColourTo(i + 1, SCE_L_SPECIAL);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chNext == '\r' || chNext == '\n') {
+ styler.ColourTo(i, SCE_L_ERROR);
+ } else {
+ if (chNext == ')') {
+ mode = 0;
+ state = SCE_L_DEFAULT;
+ }
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ break;
+ case '$' :
+ styler.ColourTo(i - 1, state);
+ styler.ColourTo(i, SCE_L_SHORTCMD);
+ mode = 0;
+ state = SCE_L_DEFAULT;
+ break;
+ case '%' :
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMENT;
+ break;
+ }
+ break;
+ case SCE_L_MATH2 :
+ switch (ch) {
+ case '\\' :
+ styler.ColourTo(i - 1, state);
+ if (latexIsLetter(chNext)) {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIsMathEnv(match, styler))
+ mode = 0;
+ }
+ }
+ state = SCE_L_COMMAND;
+ } else if (latexIsSpecial(chNext)) {
+ styler.ColourTo(i + 1, SCE_L_SPECIAL);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chNext == '\r' || chNext == '\n') {
+ styler.ColourTo(i, SCE_L_ERROR);
+ } else {
+ if (chNext == ']') {
+ mode = 0;
+ state = SCE_L_DEFAULT;
+ }
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ }
+ break;
+ case '$' :
+ styler.ColourTo(i - 1, state);
+ if (chNext == '$') {
+ styler.ColourTo(i + 1, SCE_L_SHORTCMD);
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ mode = 0;
+ state = SCE_L_DEFAULT;
+ } else { // This may not be an error, e.g.
\begin{equation}\text{$a$}\end{equation}
+ styler.ColourTo(i, SCE_L_SHORTCMD);
+ }
+ break;
+ case '%' :
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMENT;
+ break;
+ }
+ break;
+ case SCE_L_COMMENT :
+ if (ch == '\r' || ch == '\n') {
+ styler.ColourTo(i - 1, state);
+ latexStateReset(mode, state);
+ }
+ break;
+ case SCE_L_COMMENT2 :
+ if (ch == '\\') {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{comment}")) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMAND;
+ }
+ }
+ }
+ }
+ break;
+ case SCE_L_VERBATIM :
+ if (ch == '\\') {
+ int match = i + 3;
+ if (latexLastWordIs(match, styler, "\\end")) {
+ match++;
+ if (latexIsTagValid(match, lengthDoc, styler)) {
+ if (latexLastWordIs(match, styler, "{verbatim}")) {
+ styler.ColourTo(i - 1, state);
+ state = SCE_L_COMMAND;
+ }
+ }
+ }
+ } else if (chNext == chVerbatimDelim) {
+ styler.ColourTo(i + 1, state);
+ latexStateReset(mode, state);
+ chVerbatimDelim = '\0';
+ i++;
+ chNext = styler.SafeGetCharAt(i + 1);
+ } else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) {
+ styler.ColourTo(i, SCE_L_ERROR);
+ latexStateReset(mode, state);
+ chVerbatimDelim = '\0';
+ }
+ break;
+ }
+ }
+ if (lengthDoc == styler.Length()) truncModes(styler.GetLine(lengthDoc - 1));
+ styler.ColourTo(lengthDoc - 1, state);
+ styler.Flush();
+}
+
+static int latexFoldSaveToInt(const latexFoldSave &save) {
+ int sum = 0;
+ for (int i = 0; i <= save.structLev; ++i)
+ sum += save.openBegins[i];
+ return ((sum + save.structLev + SC_FOLDLEVELBASE) & SC_FOLDLEVELNUMBERMASK);
+}
+
+// Change folding state while processing a line
+// Return the level before the first relevant command
+void SCI_METHOD LexerLaTeX::Fold(unsigned int startPos, int length, int, IDocument *pAccess) {
+ const char *structWords[7] = {"part", "chapter", "section", "subsection",
+ "subsubsection", "paragraph", "subparagraph"};
+ Accessor styler(pAccess, &props);
+ unsigned int endPos = startPos + length;
+ int curLine = styler.GetLine(startPos);
+ latexFoldSave save;
+ getSave(curLine - 1, save);
+ do {
+ char ch, buf[16];
+ int i, j, lev = -1;
+ bool needFold = false;
+ for (i = static_cast<int>(startPos); i < static_cast<int>(endPos); ++i) {
+ ch = styler.SafeGetCharAt(i);
+ if (ch == '\r' || ch == '\n') break;
+ if (ch != '\\' || styler.StyleAt(i) != SCE_L_COMMAND) continue;
+ for (j = 0; j < 15 && i + 1 < static_cast<int>(endPos); ++j, ++i) {
+ buf[j] = styler.SafeGetCharAt(i + 1);
+ if (!latexIsLetter(buf[j])) break;
+ }
+ buf[j] = '\0';
+ if (strcmp(buf, "begin") == 0) {
+ if (lev < 0) lev = latexFoldSaveToInt(save);
+ ++save.openBegins[save.structLev];
+ needFold = true;
+ }
+ else if (strcmp(buf, "end") == 0) {
+ while (save.structLev > 0 && save.openBegins[save.structLev] == 0)
+ --save.structLev;
+ if (lev < 0) lev = latexFoldSaveToInt(save);
+ if (save.openBegins[save.structLev] > 0) --save.openBegins[save.structLev];
+ }
+ else {
+ for (j = 0; j < 7; ++j)
+ if (strcmp(buf, structWords[j]) == 0) break;
+ if (j >= 7) continue;
+ save.structLev = j; // level before the command
+ for (j = save.structLev + 1; j < 8; ++j) {
+ save.openBegins[save.structLev] += save.openBegins[j];
+ save.openBegins[j] = 0;
+ }
+ if (lev < 0) lev = latexFoldSaveToInt(save);
+ ++save.structLev; // level after the command
+ needFold = true;
+ }
+ }
+ if (lev < 0) lev = latexFoldSaveToInt(save);
+ if (needFold) lev |= SC_FOLDLEVELHEADERFLAG;
+ styler.SetLevel(curLine, lev);
+ setSave(curLine, save);
+ ++curLine;
+ startPos = styler.LineStart(curLine);
+ if (static_cast<int>(startPos) == styler.Length()) {
+ lev = latexFoldSaveToInt(save);
+ styler.SetLevel(curLine, lev);
+ setSave(curLine, save);
+ truncSaves(curLine);
+ }
+ } while (startPos < endPos);
+ styler.Flush();
+}
+
+static const char *const emptyWordListDesc[] = {
+ 0
+};
+
+LexerModule lmLatex(SCLEX_LATEX, LexerLaTeX::LexerFactoryLaTeX, "latex", emptyWordListDesc);
diff --git a/plugins/scintilla/scintilla/lexers/LexLua.cxx b/plugins/scintilla/scintilla/lexers/LexLua.cxx
index 9e48efc..4277d87 100644
--- a/plugins/scintilla/scintilla/lexers/LexLua.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexLua.cxx
@@ -374,7 +374,6 @@ static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, W
char chNext = styler[startPos];
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
int styleNext = styler.StyleAt(startPos);
- char s[10];
for (unsigned int i = startPos; i < lengthDoc; i++) {
char ch = chNext;
@@ -384,6 +383,7 @@ static void FoldLuaDoc(unsigned int startPos, int length, int /* initStyle */, W
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_LUA_WORD) {
if (ch == 'i' || ch == 'd' || ch == 'f' || ch == 'e' || ch == 'r' || ch == 'u') {
+ char s[10] = "";
for (unsigned int j = 0; j < 8; j++) {
if (!iswordchar(styler[i + j])) {
break;
diff --git a/plugins/scintilla/scintilla/lexers/LexMySQL.cxx b/plugins/scintilla/scintilla/lexers/LexMySQL.cxx
index 305fa74..f4823f8 100644
--- a/plugins/scintilla/scintilla/lexers/LexMySQL.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexMySQL.cxx
@@ -3,7 +3,7 @@
* @file LexMySQL.cxx
* Lexer for MySQL
*
- * Improved by Mike Lischke <mike lischke sun com>
+ * Improved by Mike Lischke <mike lischke oracle com>
* Adopted from LexSQL.cxx by Anders Karlsson <anders mysql com>
* Original work by Neil Hodgson <neilh scintilla org>
* Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
@@ -60,74 +60,99 @@ static inline bool IsANumberChar(int ch) {
/**
* Check if the current content context represent a keyword and set the context state if so.
*/
-static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[])
+static void CheckForKeyword(StyleContext& sc, WordList* keywordlists[], int activeState)
{
int length = sc.LengthCurrent() + 1; // +1 for the next char
char* s = new char[length];
sc.GetCurrentLowered(s, length);
if (keywordlists[0]->InList(s))
- sc.ChangeState(SCE_MYSQL_MAJORKEYWORD);
+ sc.ChangeState(SCE_MYSQL_MAJORKEYWORD | activeState);
else
if (keywordlists[1]->InList(s))
- sc.ChangeState(SCE_MYSQL_KEYWORD);
+ sc.ChangeState(SCE_MYSQL_KEYWORD | activeState);
else
if (keywordlists[2]->InList(s))
- sc.ChangeState(SCE_MYSQL_DATABASEOBJECT);
+ sc.ChangeState(SCE_MYSQL_DATABASEOBJECT | activeState);
else
if (keywordlists[3]->InList(s))
- sc.ChangeState(SCE_MYSQL_FUNCTION);
+ sc.ChangeState(SCE_MYSQL_FUNCTION | activeState);
else
if (keywordlists[5]->InList(s))
- sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD);
+ sc.ChangeState(SCE_MYSQL_PROCEDUREKEYWORD | activeState);
else
if (keywordlists[6]->InList(s))
- sc.ChangeState(SCE_MYSQL_USER1);
+ sc.ChangeState(SCE_MYSQL_USER1 | activeState);
else
if (keywordlists[7]->InList(s))
- sc.ChangeState(SCE_MYSQL_USER2);
+ sc.ChangeState(SCE_MYSQL_USER2 | activeState);
else
if (keywordlists[8]->InList(s))
- sc.ChangeState(SCE_MYSQL_USER3);
+ sc.ChangeState(SCE_MYSQL_USER3 | activeState);
delete [] s;
}
//--------------------------------------------------------------------------------------------------
+#define HIDDENCOMMAND_STATE 0x40 // Offset for states within a hidden command.
+#define MASKACTIVE(style) (style & ~HIDDENCOMMAND_STATE)
+
+static void SetDefaultState(StyleContext& sc, int activeState)
+{
+ if (activeState == 0)
+ sc.SetState(SCE_MYSQL_DEFAULT);
+ else
+ sc.SetState(SCE_MYSQL_HIDDENCOMMAND);
+}
+
+static void ForwardDefaultState(StyleContext& sc, int activeState)
+{
+ if (activeState == 0)
+ sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+ else
+ sc.ForwardSetState(SCE_MYSQL_HIDDENCOMMAND);
+}
+
static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
Accessor &styler)
{
- StyleContext sc(startPos, length, initStyle, styler);
+ StyleContext sc(startPos, length, initStyle, styler, 127);
+ int activeState = (initStyle == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : initStyle &
HIDDENCOMMAND_STATE;
for (; sc.More(); sc.Forward())
{
// Determine if the current state should terminate.
- switch (sc.state)
+ switch (MASKACTIVE(sc.state))
{
case SCE_MYSQL_OPERATOR:
- sc.SetState(SCE_MYSQL_DEFAULT);
+ SetDefaultState(sc, activeState);
break;
case SCE_MYSQL_NUMBER:
// We stop the number definition on non-numerical non-dot non-eE non-sign char.
if (!IsANumberChar(sc.ch))
- sc.SetState(SCE_MYSQL_DEFAULT);
+ SetDefaultState(sc, activeState);
break;
case SCE_MYSQL_IDENTIFIER:
// Switch from identifier to keyword state and open a new state for the new char.
if (!IsAWordChar(sc.ch))
{
- CheckForKeyword(sc, keywordlists);
+ CheckForKeyword(sc, keywordlists, activeState);
// Additional check for function keywords needed.
// A function name must be followed by an opening parenthesis.
- if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
- sc.ChangeState(SCE_MYSQL_DEFAULT);
+ if (MASKACTIVE(sc.state) == SCE_MYSQL_FUNCTION && sc.ch != '(')
+ {
+ if (activeState > 0)
+ sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND);
+ else
+ sc.ChangeState(SCE_MYSQL_DEFAULT);
+ }
- sc.SetState(SCE_MYSQL_DEFAULT);
+ SetDefaultState(sc, activeState);
}
break;
case SCE_MYSQL_VARIABLE:
if (!IsAWordChar(sc.ch))
- sc.SetState(SCE_MYSQL_DEFAULT);
+ SetDefaultState(sc, activeState);
break;
case SCE_MYSQL_SYSTEMVARIABLE:
if (!IsAWordChar(sc.ch))
@@ -138,10 +163,10 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
// Check for known system variables here.
if (keywordlists[4]->InList(&s[2]))
- sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE);
+ sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE | activeState);
delete [] s;
- sc.SetState(SCE_MYSQL_DEFAULT);
+ SetDefaultState(sc, activeState);
}
break;
case SCE_MYSQL_QUOTEDIDENTIFIER:
@@ -150,20 +175,19 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
if (sc.chNext == '`')
sc.Forward(); // Ignore it
else
- sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+ ForwardDefaultState(sc, activeState);
}
break;
case SCE_MYSQL_COMMENT:
- case SCE_MYSQL_HIDDENCOMMAND:
if (sc.Match('*', '/'))
{
sc.Forward();
- sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+ ForwardDefaultState(sc, activeState);
}
break;
case SCE_MYSQL_COMMENTLINE:
if (sc.atLineStart)
- sc.SetState(SCE_MYSQL_DEFAULT);
+ SetDefaultState(sc, activeState);
break;
case SCE_MYSQL_SQSTRING:
if (sc.ch == '\\')
@@ -175,7 +199,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
if (sc.chNext == '\'')
sc.Forward();
else
- sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+ ForwardDefaultState(sc, activeState);
}
break;
case SCE_MYSQL_DQSTRING:
@@ -188,76 +212,94 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
if (sc.chNext == '\"')
sc.Forward();
else
- sc.ForwardSetState(SCE_MYSQL_DEFAULT);
+ ForwardDefaultState(sc, activeState);
}
break;
+ case SCE_MYSQL_PLACEHOLDER:
+ if (sc.Match('}', '>'))
+ {
+ sc.Forward();
+ ForwardDefaultState(sc, activeState);
+ }
+ break;
+ }
+
+ if (sc.state == SCE_MYSQL_HIDDENCOMMAND && sc.Match('*', '/'))
+ {
+ activeState = 0;
+ sc.Forward();
+ ForwardDefaultState(sc, activeState);
}
// Determine if a new state should be entered.
- if (sc.state == SCE_MYSQL_DEFAULT)
+ if (sc.state == SCE_MYSQL_DEFAULT || sc.state == SCE_MYSQL_HIDDENCOMMAND)
{
switch (sc.ch)
{
case '@':
if (sc.chNext == '@')
{
- sc.SetState(SCE_MYSQL_SYSTEMVARIABLE);
+ sc.SetState(SCE_MYSQL_SYSTEMVARIABLE | activeState);
sc.Forward(2); // Skip past @@.
}
else
if (IsAWordStart(sc.ch))
{
- sc.SetState(SCE_MYSQL_VARIABLE);
+ sc.SetState(SCE_MYSQL_VARIABLE | activeState);
sc.Forward(); // Skip past @.
}
else
- sc.SetState(SCE_MYSQL_OPERATOR);
+ sc.SetState(SCE_MYSQL_OPERATOR | activeState);
break;
case '`':
- sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER);
+ sc.SetState(SCE_MYSQL_QUOTEDIDENTIFIER | activeState);
break;
case '#':
- sc.SetState(SCE_MYSQL_COMMENTLINE);
+ sc.SetState(SCE_MYSQL_COMMENTLINE | activeState);
break;
case '\'':
- sc.SetState(SCE_MYSQL_SQSTRING);
+ sc.SetState(SCE_MYSQL_SQSTRING | activeState);
break;
case '\"':
- sc.SetState(SCE_MYSQL_DQSTRING);
+ sc.SetState(SCE_MYSQL_DQSTRING | activeState);
break;
default:
if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
- sc.SetState(SCE_MYSQL_NUMBER);
+ sc.SetState(SCE_MYSQL_NUMBER | activeState);
else
if (IsAWordStart(sc.ch))
- sc.SetState(SCE_MYSQL_IDENTIFIER);
+ sc.SetState(SCE_MYSQL_IDENTIFIER | activeState);
else
if (sc.Match('/', '*'))
{
- sc.SetState(SCE_MYSQL_COMMENT);
+ sc.SetState(SCE_MYSQL_COMMENT | activeState);
// Skip comment introducer and check for hidden command.
sc.Forward(2);
if (sc.ch == '!')
{
+ activeState = HIDDENCOMMAND_STATE;
sc.ChangeState(SCE_MYSQL_HIDDENCOMMAND);
- sc.Forward();
}
}
+ else if (sc.Match('<', '{'))
+ {
+ sc.SetState(SCE_MYSQL_PLACEHOLDER | activeState);
+ }
else
if (sc.Match("--"))
{
// Special MySQL single line comment.
- sc.SetState(SCE_MYSQL_COMMENTLINE);
+ sc.SetState(SCE_MYSQL_COMMENTLINE | activeState);
sc.Forward(2);
// Check the third character too. It must be a space or EOL.
if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r')
- sc.ChangeState(SCE_MYSQL_OPERATOR);
+ sc.ChangeState(SCE_MYSQL_OPERATOR | activeState);
}
else
if (isoperator(static_cast<char>(sc.ch)))
- sc.SetState(SCE_MYSQL_OPERATOR);
+ sc.SetState(SCE_MYSQL_OPERATOR | activeState);
}
}
}
@@ -266,12 +308,12 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
// also at the end of a line.
if (sc.state == SCE_MYSQL_IDENTIFIER)
{
- CheckForKeyword(sc, keywordlists);
+ CheckForKeyword(sc, keywordlists, activeState);
// Additional check for function keywords needed.
// A function name must be followed by an opening parenthesis.
if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
- sc.ChangeState(SCE_MYSQL_DEFAULT);
+ SetDefaultState(sc, activeState);
}
sc.Complete();
@@ -284,7 +326,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
*/
static bool IsStreamCommentStyle(int style)
{
- return style == SCE_MYSQL_COMMENT;
+ return MASKACTIVE(style) == SCE_MYSQL_COMMENT;
}
//--------------------------------------------------------------------------------------------------
@@ -323,6 +365,7 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
+ int activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE;
bool endPending = false;
bool whenPending = false;
@@ -332,30 +375,23 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
for (unsigned int i = startPos; length > 0; i++, length--)
{
int stylePrev = style;
+ int lastActiveState = activeState;
style = styleNext;
styleNext = styler.StyleAt(i + 1);
+ activeState = (style == SCE_MYSQL_HIDDENCOMMAND) ? HIDDENCOMMAND_STATE : style & HIDDENCOMMAND_STATE;
char currentChar = nextChar;
nextChar = styler.SafeGetCharAt(i + 1);
bool atEOL = (currentChar == '\r' && nextChar != '\n') || (currentChar == '\n');
- switch (style)
+ switch (MASKACTIVE(style))
{
case SCE_MYSQL_COMMENT:
if (foldComment)
{
- // Multiline comment style /* .. */.
- if (IsStreamCommentStyle(style))
- {
- // Increase level if we just start a foldable comment.
- if (!IsStreamCommentStyle(stylePrev))
- levelNext++;
- else
- // If we are in the middle of a foldable comment check if it ends now.
- // Don't end at the line end, though.
- if (!IsStreamCommentStyle(styleNext) && !atEOL)
- levelNext--;
- }
+ // Multiline comment style /* .. */ just started or is still in progress.
+ if (IsStreamCommentStyle(style) && !IsStreamCommentStyle(stylePrev))
+ levelNext++;
}
break;
case SCE_MYSQL_COMMENTLINE:
@@ -377,6 +413,7 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
}
break;
case SCE_MYSQL_HIDDENCOMMAND:
+ /*
if (endPending)
{
// A conditional command is not a white space so it should end the current block
@@ -386,15 +423,9 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
}
- if (style != stylePrev)
+ }*/
+ if (activeState != lastActiveState)
levelNext++;
- else
- if (style != styleNext)
- {
- levelNext--;
- if (levelNext < SC_FOLDLEVELBASE)
- levelNext = SC_FOLDLEVELBASE;
- }
break;
case SCE_MYSQL_OPERATOR:
if (endPending)
@@ -480,7 +511,7 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
break;
default:
- if (!isspace(currentChar) && endPending)
+ if (!isspacechar(currentChar) && endPending)
{
// END followed by a non-whitespace character (not covered by other cases like identifiers)
// also should end a folding block. Typical case: END followed by self defined delimiter.
@@ -490,7 +521,23 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
}
break;
}
-
+
+ // Go up one level if we just ended a multi line comment.
+ if (IsStreamCommentStyle(stylePrev) && !IsStreamCommentStyle(style))
+ {
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
+
+ if (activeState == 0 && lastActiveState != 0)
+ {
+ // Decrease fold level when we left a hidden command.
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
+
if (atEOL)
{
// Apply the new folding level to this line.
@@ -530,4 +577,4 @@ static const char * const mysqlWordListDesc[] = {
0
};
-LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc);
+LexerModule lmMySQL(SCLEX_MYSQL, ColouriseMySQLDoc, "mysql", FoldMySQLDoc, mysqlWordListDesc, 7);
diff --git a/plugins/scintilla/scintilla/lexers/LexOthers.cxx
b/plugins/scintilla/scintilla/lexers/LexOthers.cxx
index 259059f..8299781 100644
--- a/plugins/scintilla/scintilla/lexers/LexOthers.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexOthers.cxx
@@ -1,7 +1,6 @@
// Scintilla source code edit control
/** @file LexOthers.cxx
** Lexers for batch files, diff results, properties files, make files and error lists.
- ** Also lexer for LaTeX documents.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
@@ -560,7 +559,7 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
}
static void ColouriseDiffDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- char lineBuffer[DIFF_BUFFER_START_SIZE];
+ char lineBuffer[DIFF_BUFFER_START_SIZE] = "";
styler.StartAt(startPos);
styler.StartSegment(startPos);
unsigned int linePos = 0;
@@ -614,78 +613,6 @@ static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Ac
} while (static_cast<int>(startPos) + length > curLineStart);
}
-static void ColourisePoLine(
- char *lineBuffer,
- unsigned int lengthLine,
- unsigned int startLine,
- unsigned int endPos,
- Accessor &styler) {
-
- unsigned int i = 0;
- static unsigned int state = SCE_PO_DEFAULT;
- unsigned int state_start = SCE_PO_DEFAULT;
-
- while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
- i++;
- if (i < lengthLine) {
- if (lineBuffer[i] == '#') {
- // check if the comment contains any flags ("#, ") and
- // then whether the flags contain "fuzzy"
- if (strstart(lineBuffer, "#, ") && strstr(lineBuffer, "fuzzy"))
- styler.ColourTo(endPos, SCE_PO_FUZZY);
- else
- styler.ColourTo(endPos, SCE_PO_COMMENT);
- } else {
- if (lineBuffer[0] == '"') {
- // line continuation, use previous style
- styler.ColourTo(endPos, state);
- return;
- // this implicitly also matches "msgid_plural"
- } else if (strstart(lineBuffer, "msgid")) {
- state_start = SCE_PO_MSGID;
- state = SCE_PO_MSGID_TEXT;
- } else if (strstart(lineBuffer, "msgstr")) {
- state_start = SCE_PO_MSGSTR;
- state = SCE_PO_MSGSTR_TEXT;
- } else if (strstart(lineBuffer, "msgctxt")) {
- state_start = SCE_PO_MSGCTXT;
- state = SCE_PO_MSGCTXT_TEXT;
- }
- if (state_start != SCE_PO_DEFAULT) {
- // find the next space
- while ((i < lengthLine) && ! isspacechar(lineBuffer[i]))
- i++;
- styler.ColourTo(startLine + i - 1, state_start);
- styler.ColourTo(startLine + i, SCE_PO_DEFAULT);
- styler.ColourTo(endPos, state);
- }
- }
- } else {
- styler.ColourTo(endPos, SCE_PO_DEFAULT);
- }
-}
-
-static void ColourisePoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- char lineBuffer[1024];
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- unsigned int linePos = 0;
- unsigned int startLine = startPos;
- for (unsigned int i = startPos; i < startPos + length; i++) {
- lineBuffer[linePos++] = styler[i];
- if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
- // End of line (or of line buffer) met, colourise it
- lineBuffer[linePos] = '\0';
- ColourisePoLine(lineBuffer, linePos, startLine, i, styler);
- linePos = 0;
- startLine = i + 1;
- }
- }
- if (linePos > 0) { // Last line does not have ending characters
- ColourisePoLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
- }
-}
-
static inline bool isassignchar(unsigned char ch) {
return (ch == '=') || (ch == ':');
}
@@ -857,17 +784,19 @@ static void ColouriseMakeLine(
while ((i < lengthLine) && isspacechar(lineBuffer[i])) {
i++;
}
- if (lineBuffer[i] == '#') { // Comment
- styler.ColourTo(endPos, SCE_MAKE_COMMENT);
- return;
- }
- if (lineBuffer[i] == '!') { // Special directive
- styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
- return;
+ if (i < lengthLine) {
+ if (lineBuffer[i] == '#') { // Comment
+ styler.ColourTo(endPos, SCE_MAKE_COMMENT);
+ return;
+ }
+ if (lineBuffer[i] == '!') { // Special directive
+ styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
+ return;
+ }
}
int varCount = 0;
while (i < lengthLine) {
- if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
+ if (((i + 1) < lengthLine) && (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(')) {
styler.ColourTo(startLine + i - 1, state);
state = SCE_MAKE_IDENTIFIER;
varCount++;
@@ -1013,6 +942,10 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
strstr(lineBuffer, ".java:")) {
// Java stack back trace
return SCE_ERR_JAVA_STACK;
+ } else if (strstart(lineBuffer, "In file included from ") ||
+ strstart(lineBuffer, " from ")) {
+ // GCC showing include path to following error
+ return SCE_ERR_GCC_INCLUDED_FROM;
} else {
// Look for one of the following formats:
// GCC: <filename>:<line>:<message>
@@ -1179,301 +1112,6 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
}
}
-static bool latexIsSpecial(int ch) {
- return (ch == '#') || (ch == '$') || (ch == '%') || (ch == '&') || (ch == '_') ||
- (ch == '{') || (ch == '}') || (ch == ' ');
-}
-
-static bool latexIsBlank(int ch) {
- return (ch == ' ') || (ch == '\t');
-}
-
-static bool latexIsBlankAndNL(int ch) {
- return (ch == ' ') || (ch == '\t') || (ch == '\r') || (ch == '\n');
-}
-
-static bool latexIsLetter(int ch) {
- return isascii(ch) && isalpha(ch);
-}
-
-static bool latexIsTagValid(int &i, int l, Accessor &styler) {
- while (i < l) {
- if (styler.SafeGetCharAt(i) == '{') {
- while (i < l) {
- i++;
- if (styler.SafeGetCharAt(i) == '}') {
- return true;
- } else if (!latexIsLetter(styler.SafeGetCharAt(i)) &&
- styler.SafeGetCharAt(i)!='*') {
- return false;
- }
- }
- } else if (!latexIsBlank(styler.SafeGetCharAt(i))) {
- return false;
- }
- i++;
- }
- return false;
-}
-
-static bool latexNextNotBlankIs(int i, int l, Accessor &styler, char needle) {
- char ch;
- while (i < l) {
- ch = styler.SafeGetCharAt(i);
- if (!latexIsBlankAndNL(ch) && ch != '*') {
- if (ch == needle)
- return true;
- else
- return false;
- }
- i++;
- }
- return false;
-}
-
-static bool latexLastWordIs(int start, Accessor &styler, const char *needle) {
- unsigned int i = 0;
- unsigned int l = static_cast<unsigned int>(strlen(needle));
- int ini = start-l+1;
- char s[32];
-
- while (i < l && i < 32) {
- s[i] = styler.SafeGetCharAt(ini + i);
- i++;
- }
- s[i] = '\0';
-
- return (strcmp(s, needle) == 0);
-}
-
-static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
-
- styler.StartAt(startPos);
-
- int state = initStyle;
- char chNext = styler.SafeGetCharAt(startPos);
- styler.StartSegment(startPos);
- int lengthDoc = startPos + length;
- char chVerbatimDelim = '\0';
-
- for (int i = startPos; i < lengthDoc; i++) {
- char ch = chNext;
- chNext = styler.SafeGetCharAt(i + 1);
-
- if (styler.IsLeadByte(ch)) {
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- continue;
- }
-
- switch (state) {
- case SCE_L_DEFAULT :
- switch (ch) {
- case '\\' :
- styler.ColourTo(i - 1, state);
- if (latexIsSpecial(chNext)) {
- state = SCE_L_SPECIAL;
- } else {
- if (latexIsLetter(chNext)) {
- state = SCE_L_COMMAND;
- } else {
- if (chNext == '(' || chNext == '[') {
- styler.ColourTo(i-1, state);
- styler.ColourTo(i+1, SCE_L_SHORTCMD);
- state = SCE_L_MATH;
- if (chNext == '[')
- state = SCE_L_MATH2;
- i++;
- chNext = styler.SafeGetCharAt(i+1);
- } else {
- state = SCE_L_SHORTCMD;
- }
- }
- }
- break;
- case '$' :
- styler.ColourTo(i - 1, state);
- state = SCE_L_MATH;
- if (chNext == '$') {
- state = SCE_L_MATH2;
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- }
- break;
- case '%' :
- styler.ColourTo(i - 1, state);
- state = SCE_L_COMMENT;
- break;
- }
- break;
- case SCE_L_ERROR:
- styler.ColourTo(i-1, state);
- state = SCE_L_DEFAULT;
- break;
- case SCE_L_SPECIAL:
- case SCE_L_SHORTCMD:
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- break;
- case SCE_L_COMMAND :
- if (!latexIsLetter(chNext)) {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- if (latexNextNotBlankIs(i+1, lengthDoc, styler, '[' )) {
- state = SCE_L_CMDOPT;
- } else if (latexLastWordIs(i, styler, "\\begin")) {
- state = SCE_L_TAG;
- } else if (latexLastWordIs(i, styler, "\\end")) {
- state = SCE_L_TAG2;
- } else if (latexLastWordIs(i, styler, "\\verb") &&
- chNext != '*' && chNext != ' ') {
- chVerbatimDelim = chNext;
- state = SCE_L_VERBATIM;
- }
- }
- break;
- case SCE_L_CMDOPT :
- if (ch == ']') {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- }
- break;
- case SCE_L_TAG :
- if (latexIsTagValid(i, lengthDoc, styler)) {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- if (latexLastWordIs(i, styler, "{verbatim}")) {
- state = SCE_L_VERBATIM;
- } else if (latexLastWordIs(i, styler, "{comment}")) {
- state = SCE_L_COMMENT2;
- } else if (latexLastWordIs(i, styler, "{math}")) {
- state = SCE_L_MATH;
- } else if (latexLastWordIs(i, styler, "{displaymath}")) {
- state = SCE_L_MATH2;
- } else if (latexLastWordIs(i, styler, "{equation}")) {
- state = SCE_L_MATH2;
- }
- } else {
- state = SCE_L_ERROR;
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- }
- chNext = styler.SafeGetCharAt(i+1);
- break;
- case SCE_L_TAG2 :
- if (latexIsTagValid(i, lengthDoc, styler)) {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- } else {
- state = SCE_L_ERROR;
- }
- chNext = styler.SafeGetCharAt(i+1);
- break;
- case SCE_L_MATH :
- if (ch == '$') {
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- } else if (ch == '\\' && chNext == ')') {
- styler.ColourTo(i-1, state);
- styler.ColourTo(i+1, SCE_L_SHORTCMD);
- i++;
- chNext = styler.SafeGetCharAt(i+1);
- state = SCE_L_DEFAULT;
- } else if (ch == '\\') {
- int match = i + 3;
- if (latexLastWordIs(match, styler, "\\end")) {
- match++;
- if (latexIsTagValid(match, lengthDoc, styler)) {
- if (latexLastWordIs(match, styler, "{math}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- }
- }
- }
- }
-
- break;
- case SCE_L_MATH2 :
- if (ch == '$') {
- if (chNext == '$') {
- i++;
- chNext = styler.SafeGetCharAt(i + 1);
- styler.ColourTo(i, state);
- state = SCE_L_DEFAULT;
- } else {
- styler.ColourTo(i, SCE_L_ERROR);
- state = SCE_L_DEFAULT;
- }
- } else if (ch == '\\' && chNext == ']') {
- styler.ColourTo(i-1, state);
- styler.ColourTo(i+1, SCE_L_SHORTCMD);
- i++;
- chNext = styler.SafeGetCharAt(i+1);
- state = SCE_L_DEFAULT;
- } else if (ch == '\\') {
- int match = i + 3;
- if (latexLastWordIs(match, styler, "\\end")) {
- match++;
- if (latexIsTagValid(match, lengthDoc, styler)) {
- if (latexLastWordIs(match, styler, "{displaymath}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- } else if (latexLastWordIs(match, styler, "{equation}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- }
- }
- }
- }
- break;
- case SCE_L_COMMENT :
- if (ch == '\r' || ch == '\n') {
- styler.ColourTo(i - 1, state);
- state = SCE_L_DEFAULT;
- }
- break;
- case SCE_L_COMMENT2 :
- if (ch == '\\') {
- int match = i + 3;
- if (latexLastWordIs(match, styler, "\\end")) {
- match++;
- if (latexIsTagValid(match, lengthDoc, styler)) {
- if (latexLastWordIs(match, styler, "{comment}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- }
- }
- }
- }
- break;
- case SCE_L_VERBATIM :
- if (ch == '\\') {
- int match = i + 3;
- if (latexLastWordIs(match, styler, "\\end")) {
- match++;
- if (latexIsTagValid(match, lengthDoc, styler)) {
- if (latexLastWordIs(match, styler, "{verbatim}")) {
- styler.ColourTo(i-1, state);
- state = SCE_L_COMMAND;
- }
- }
- }
- } else if (chNext == chVerbatimDelim) {
- styler.ColourTo(i+1, state);
- state = SCE_L_DEFAULT;
- chVerbatimDelim = '\0';
- } else if (chVerbatimDelim != '\0' && (ch == '\n' || ch == '\r')) {
- styler.ColourTo(i, SCE_L_ERROR);
- state = SCE_L_DEFAULT;
- chVerbatimDelim = '\0';
- }
- break;
- }
- }
- styler.ColourTo(lengthDoc-1, state);
-}
-
static const char *const batchWordListDesc[] = {
"Internal Commands",
"External Commands",
@@ -1496,9 +1134,7 @@ static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[
LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
-LexerModule lmPo(SCLEX_PO, ColourisePoDoc, "po", 0, emptyWordListDesc);
LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);
LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
-LexerModule lmLatex(SCLEX_LATEX, ColouriseLatexDoc, "latex", 0, emptyWordListDesc);
LexerModule lmNull(SCLEX_NULL, ColouriseNullDoc, "null");
diff --git a/plugins/scintilla/scintilla/lexers/LexPO.cxx b/plugins/scintilla/scintilla/lexers/LexPO.cxx
new file mode 100644
index 0000000..7b44107
--- /dev/null
+++ b/plugins/scintilla/scintilla/lexers/LexPO.cxx
@@ -0,0 +1,213 @@
+// Scintilla source code edit control
+/** @file LexPO.cxx
+ ** Lexer for GetText Translation (PO) files.
+ **/
+// Copyright 2012 by Colomban Wendling <ban herbesfolles org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// see https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files for the syntax reference
+// some details are taken from the GNU msgfmt behavior (like that indent is allows in front of lines)
+
+// TODO:
+// * add keywords for flags (fuzzy, c-format, ...)
+// * highlight formats inside c-format strings (%s, %d, etc.)
+// * style for previous untranslated string? ("#|" comment)
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static void ColourisePODoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler)
{
+ StyleContext sc(startPos, length, initStyle, styler);
+ bool escaped = false;
+ int curLine = styler.GetLine(startPos);
+ // the line state holds the last state on or before the line that isn't the default style
+ int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : SCE_PO_DEFAULT;
+
+ for (; sc.More(); sc.Forward()) {
+ // whether we should leave a state
+ switch (sc.state) {
+ case SCE_PO_COMMENT:
+ case SCE_PO_PROGRAMMER_COMMENT:
+ case SCE_PO_REFERENCE:
+ case SCE_PO_FLAGS:
+ case SCE_PO_FUZZY:
+ if (sc.atLineEnd)
+ sc.SetState(SCE_PO_DEFAULT);
+ else if (sc.state == SCE_PO_FLAGS && sc.Match("fuzzy"))
+ // here we behave like the previous parser, but this should probably
be highlighted
+ // on its own like a keyword rather than changing the whole flags
style
+ sc.ChangeState(SCE_PO_FUZZY);
+ break;
+
+ case SCE_PO_MSGCTXT:
+ case SCE_PO_MSGID:
+ case SCE_PO_MSGSTR:
+ if (isspacechar(sc.ch))
+ sc.SetState(SCE_PO_DEFAULT);
+ break;
+
+ case SCE_PO_ERROR:
+ if (sc.atLineEnd)
+ sc.SetState(SCE_PO_DEFAULT);
+ break;
+
+ case SCE_PO_MSGCTXT_TEXT:
+ case SCE_PO_MSGID_TEXT:
+ case SCE_PO_MSGSTR_TEXT:
+ if (sc.atLineEnd) { // invalid inside a string
+ if (sc.state == SCE_PO_MSGCTXT_TEXT)
+ sc.ChangeState(SCE_PO_MSGCTXT_TEXT_EOL);
+ else if (sc.state == SCE_PO_MSGID_TEXT)
+ sc.ChangeState(SCE_PO_MSGID_TEXT_EOL);
+ else if (sc.state == SCE_PO_MSGSTR_TEXT)
+ sc.ChangeState(SCE_PO_MSGSTR_TEXT_EOL);
+ sc.SetState(SCE_PO_DEFAULT);
+ escaped = false;
+ } else {
+ if (escaped)
+ escaped = false;
+ else if (sc.ch == '\\')
+ escaped = true;
+ else if (sc.ch == '"')
+ sc.ForwardSetState(SCE_PO_DEFAULT);
+ }
+ break;
+ }
+
+ // whether we should enter a new state
+ if (sc.state == SCE_PO_DEFAULT) {
+ // forward to the first non-white character on the line
+ bool atLineStart = sc.atLineStart;
+ if (atLineStart) {
+ // reset line state if it is set to comment state so empty lines don't get
+ // comment line state, and the folding code folds comments separately,
+ // and anyway the styling don't use line state for comments
+ if (curLineState == SCE_PO_COMMENT)
+ curLineState = SCE_PO_DEFAULT;
+
+ while (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch))
+ sc.Forward();
+ }
+
+ if (atLineStart && sc.ch == '#') {
+ if (sc.chNext == '.')
+ sc.SetState(SCE_PO_PROGRAMMER_COMMENT);
+ else if (sc.chNext == ':')
+ sc.SetState(SCE_PO_REFERENCE);
+ else if (sc.chNext == ',')
+ sc.SetState(SCE_PO_FLAGS);
+ else
+ sc.SetState(SCE_PO_COMMENT);
+ } else if (atLineStart && sc.Match("msgid")) { // includes msgid_plural
+ sc.SetState(SCE_PO_MSGID);
+ } else if (atLineStart && sc.Match("msgstr")) { // includes [] suffixes
+ sc.SetState(SCE_PO_MSGSTR);
+ } else if (atLineStart && sc.Match("msgctxt")) {
+ sc.SetState(SCE_PO_MSGCTXT);
+ } else if (sc.ch == '"') {
+ if (curLineState == SCE_PO_MSGCTXT || curLineState == SCE_PO_MSGCTXT_TEXT)
+ sc.SetState(SCE_PO_MSGCTXT_TEXT);
+ else if (curLineState == SCE_PO_MSGID || curLineState == SCE_PO_MSGID_TEXT)
+ sc.SetState(SCE_PO_MSGID_TEXT);
+ else if (curLineState == SCE_PO_MSGSTR || curLineState == SCE_PO_MSGSTR_TEXT)
+ sc.SetState(SCE_PO_MSGSTR_TEXT);
+ else
+ sc.SetState(SCE_PO_ERROR);
+ } else if (! isspacechar(sc.ch))
+ sc.SetState(SCE_PO_ERROR);
+
+ if (sc.state != SCE_PO_DEFAULT)
+ curLineState = sc.state;
+ }
+
+ if (sc.atLineEnd) {
+ // Update the line state, so it can be seen by next line
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, curLineState);
+ }
+ }
+ sc.Complete();
+}
+
+static int FindNextNonEmptyLineState(unsigned int startPos, Accessor &styler) {
+ unsigned int length = styler.Length();
+ for (unsigned int i = startPos; i < length; i++) {
+ if (! isspacechar(styler[i])) {
+ return styler.GetLineState(styler.GetLine(i));
+ }
+ }
+ return 0;
+}
+
+static void FoldPODoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
+ if (! styler.GetPropertyInt("fold"))
+ return;
+ bool foldCompact = styler.GetPropertyInt("fold.compact") != 0;
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+
+ unsigned int endPos = startPos + length;
+ int curLine = styler.GetLine(startPos);
+ int lineState = styler.GetLineState(curLine);
+ int nextLineState;
+ int level = styler.LevelAt(curLine) & SC_FOLDLEVELNUMBERMASK;
+ int nextLevel;
+ int visible = 0;
+ int chNext = styler[startPos];
+
+ for (unsigned int i = startPos; i < endPos; i++) {
+ int ch = chNext;
+ chNext = styler.SafeGetCharAt(i+1);
+
+ if (! isspacechar(ch)) {
+ visible++;
+ } else if ((ch == '\r' && chNext != '\n') || ch == '\n' || i+1 >= endPos) {
+ int lvl = level;
+ int nextLine = curLine + 1;
+
+ nextLineState = styler.GetLineState(nextLine);
+ if ((lineState != SCE_PO_COMMENT || foldComment) &&
+ nextLineState == lineState &&
+ FindNextNonEmptyLineState(i, styler) == lineState)
+ nextLevel = SC_FOLDLEVELBASE + 1;
+ else
+ nextLevel = SC_FOLDLEVELBASE;
+
+ if (nextLevel > level)
+ lvl |= SC_FOLDLEVELHEADERFLAG;
+ if (visible == 0 && foldCompact)
+ lvl |= SC_FOLDLEVELWHITEFLAG;
+
+ styler.SetLevel(curLine, lvl);
+
+ lineState = nextLineState;
+ curLine = nextLine;
+ level = nextLevel;
+ visible = 0;
+ }
+ }
+}
+
+static const char *const poWordListDesc[] = {
+ 0
+};
+
+LexerModule lmPO(SCLEX_PO, ColourisePODoc, "po", FoldPODoc, poWordListDesc);
diff --git a/plugins/scintilla/scintilla/lexers/LexRuby.cxx b/plugins/scintilla/scintilla/lexers/LexRuby.cxx
index 23115e6..40424aa 100644
--- a/plugins/scintilla/scintilla/lexers/LexRuby.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexRuby.cxx
@@ -465,7 +465,9 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
}
prevStyle = styler.StyleAt(firstWordPosn);
// If we have '<<' following a keyword, it's not a heredoc
- if (prevStyle != SCE_RB_IDENTIFIER) {
+ if (prevStyle != SCE_RB_IDENTIFIER
+ && prevStyle != SCE_RB_INSTANCE_VAR
+ && prevStyle != SCE_RB_CLASS_VAR) {
return definitely_not_a_here_doc;
}
int newStyle = prevStyle;
@@ -495,6 +497,9 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
} else {
break;
}
+ // on second and next passes, only identifiers may appear since
+ // class and instance variable are private
+ prevStyle = SCE_RB_IDENTIFIER;
}
// Skip next batch of white-space
firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler);
@@ -1436,7 +1441,8 @@ static bool keywordIsAmbiguous(const char *prevWord)
|| !strcmp(prevWord, "do")
|| !strcmp(prevWord, "while")
|| !strcmp(prevWord, "unless")
- || !strcmp(prevWord, "until")) {
+ || !strcmp(prevWord, "until")
+ || !strcmp(prevWord, "for")) {
return true;
} else {
return false;
@@ -1554,6 +1560,7 @@ static bool keywordIsModifier(const char *word,
#define WHILE_BACKWARDS "elihw"
#define UNTIL_BACKWARDS "litnu"
+#define FOR_BACKWARDS "rof"
// Nothing fancy -- look to see if we follow a while/until somewhere
// on the current line
@@ -1591,7 +1598,8 @@ static bool keywordDoStartsLoop(int pos,
*dst = 0;
// Did we see our keyword?
if (!strcmp(prevWord, WHILE_BACKWARDS)
- || !strcmp(prevWord, UNTIL_BACKWARDS)) {
+ || !strcmp(prevWord, UNTIL_BACKWARDS)
+ || !strcmp(prevWord, FOR_BACKWARDS)) {
return true;
}
// We can move pos to the beginning of the keyword, and then
diff --git a/plugins/scintilla/scintilla/lexers/LexSQL.cxx b/plugins/scintilla/scintilla/lexers/LexSQL.cxx
index d9013db..dc4bf66 100644
--- a/plugins/scintilla/scintilla/lexers/LexSQL.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexSQL.cxx
@@ -122,13 +122,11 @@ public :
return sqlStatesLine;
}
-
- unsigned short int IntoSelectStatement (unsigned short int sqlStatesLine, bool found) {
+ unsigned short int IntoSelectStatementOrAssignment (unsigned short int sqlStatesLine, bool found) {
if (found)
- sqlStatesLine |= MASK_INTO_SELECT_STATEMENT;
+ sqlStatesLine |= MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT;
else
- sqlStatesLine &= ~MASK_INTO_SELECT_STATEMENT;
-
+ sqlStatesLine &= ~MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT;
return sqlStatesLine;
}
@@ -161,11 +159,9 @@ public :
bool IsIntoExceptionBlock (unsigned short int sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;
}
-
- bool IsIntoSelectStatement (unsigned short int sqlStatesLine) {
- return (sqlStatesLine & MASK_INTO_SELECT_STATEMENT) != 0;
+ bool IsIntoSelectStatementOrAssignment (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT) != 0;
}
-
bool IsCaseMergeWithoutWhenFound (unsigned short int sqlStatesLine) {
return (sqlStatesLine & MASK_CASE_MERGE_WITHOUT_WHEN_FOUND) != 0;
}
@@ -188,7 +184,7 @@ private :
SparseState <unsigned short int> sqlStatement;
enum {
MASK_NESTED_CASES = 0x01FF,
- MASK_INTO_SELECT_STATEMENT = 0x0200,
+ MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT = 0x0200,
MASK_CASE_MERGE_WITHOUT_WHEN_FOUND = 0x0400,
MASK_MERGE_STATEMENT = 0x0800,
MASK_INTO_DECLARE = 0x1000,
@@ -608,9 +604,12 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine,
false);
levelNext--;
}
- if (sqlStates.IsIntoSelectStatement(sqlStatesCurrentLine))
- sqlStatesCurrentLine = sqlStates.IntoSelectStatement(sqlStatesCurrentLine,
false);
+ if (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine))
+ sqlStatesCurrentLine =
sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, false);
}
+ if (ch == ':' && chNext == '=' && !IsCommentStyle(style))
+ sqlStatesCurrentLine =
sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true);
+
if (options.foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
levelNext++;
@@ -666,10 +665,9 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
} else {
s[j] = '\0';
}
-
if (!options.foldOnlyBegin &&
strcmp(s, "select") == 0) {
- sqlStatesCurrentLine = sqlStates.IntoSelectStatement(sqlStatesCurrentLine,
true);
+ sqlStatesCurrentLine =
sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true);
} else if (strcmp(s, "if") == 0) {
if (endFound) {
endFound = false;
@@ -719,8 +717,10 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
levelNext--; //again for the "end case;" and block
when
}
} else if (!options.foldOnlyBegin) {
- if (strcmp(s, "case") == 0)
+ if (strcmp(s, "case") == 0) {
sqlStatesCurrentLine =
sqlStates.BeginCaseBlock(sqlStatesCurrentLine);
+ sqlStatesCurrentLine =
sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
+ }
if (levelCurrent > levelNext)
levelCurrent = levelNext;
@@ -728,7 +728,6 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
if (!statementFound)
levelNext++;
- sqlStatesCurrentLine =
sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
statementFound = true;
} else if (levelCurrent > levelNext) {
// doesn't include this line into the folding block
@@ -765,7 +764,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
(strcmp(s, "endif") == 0)) {
endFound = true;
levelNext--;
- if (sqlStates.IsIntoSelectStatement(sqlStatesCurrentLine) &&
!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
+ if (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine) &&
!sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
levelNext--;
if (levelNext < SC_FOLDLEVELBASE) {
levelNext = SC_FOLDLEVELBASE;
diff --git a/plugins/scintilla/scintilla/lexers/LexYAML.cxx b/plugins/scintilla/scintilla/lexers/LexYAML.cxx
index 727e8af..c808d97 100644
--- a/plugins/scintilla/scintilla/lexers/LexYAML.cxx
+++ b/plugins/scintilla/scintilla/lexers/LexYAML.cxx
@@ -169,7 +169,7 @@ static void ColouriseYAMLLine(
}
static void ColouriseYAMLDoc(unsigned int startPos, int length, int, WordList *keywordLists[], Accessor
&styler) {
- char lineBuffer[1024];
+ char lineBuffer[1024] = "";
styler.StartAt(startPos);
styler.StartSegment(startPos);
unsigned int linePos = 0;
diff --git a/plugins/scintilla/scintilla/lexlib/CharacterSet.h
b/plugins/scintilla/scintilla/lexlib/CharacterSet.h
index ba42ea3..a0c45b2 100644
--- a/plugins/scintilla/scintilla/lexlib/CharacterSet.h
+++ b/plugins/scintilla/scintilla/lexlib/CharacterSet.h
@@ -40,11 +40,32 @@ public:
if (base & setDigits)
AddString("0123456789");
}
+ CharacterSet(const CharacterSet &other) {
+ size = other.size;
+ valueAfter = other.valueAfter;
+ bset = new bool[size];
+ for (int i=0; i < size; i++) {
+ bset[i] = other.bset[i];
+ }
+ }
~CharacterSet() {
delete []bset;
bset = 0;
size = 0;
}
+ CharacterSet &operator=(const CharacterSet &other) {
+ if (this != &other) {
+ bool *bsetNew = new bool[other.size];
+ for (int i=0; i < other.size; i++) {
+ bsetNew[i] = other.bset[i];
+ }
+ delete []bset;
+ size = other.size;
+ valueAfter = other.valueAfter;
+ bset = bsetNew;
+ }
+ return *this;
+ }
void Add(int val) {
assert(val >= 0);
assert(val < size);
@@ -90,7 +111,15 @@ inline bool IsADigit(int ch, int base) {
}
inline bool IsASCII(int ch) {
- return ch < 0x80;
+ return (ch >= 0) && (ch < 0x80);
+}
+
+inline bool IsLowerCase(int ch) {
+ return (ch >= 'a') && (ch <= 'z');
+}
+
+inline bool IsUpperCase(int ch) {
+ return (ch >= 'A') && (ch <= 'Z');
}
inline bool IsAlphaNumeric(int ch) {
@@ -109,15 +138,15 @@ inline bool isspacechar(int ch) {
}
inline bool iswordchar(int ch) {
- return IsASCII(ch) && (IsAlphaNumeric(ch) || ch == '.' || ch == '_');
+ return IsAlphaNumeric(ch) || ch == '.' || ch == '_';
}
inline bool iswordstart(int ch) {
- return IsASCII(ch) && (IsAlphaNumeric(ch) || ch == '_');
+ return IsAlphaNumeric(ch) || ch == '_';
}
inline bool isoperator(int ch) {
- if (IsASCII(ch) && IsAlphaNumeric(ch))
+ if (IsAlphaNumeric(ch))
return false;
if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
diff --git a/plugins/scintilla/scintilla/lexlib/LexAccessor.h
b/plugins/scintilla/scintilla/lexlib/LexAccessor.h
index c38392e..59ae113 100644
--- a/plugins/scintilla/scintilla/lexlib/LexAccessor.h
+++ b/plugins/scintilla/scintilla/lexlib/LexAccessor.h
@@ -12,6 +12,8 @@
namespace Scintilla {
#endif
+enum EncodingType { enc8bit, encUnicode, encDBCS };
+
class LexAccessor {
private:
IDocument *pAccess;
@@ -25,6 +27,7 @@ private:
int startPos;
int endPos;
int codePage;
+ enum EncodingType encodingType;
int lenDoc;
int mask;
char styleBuf[bufferSize];
@@ -33,6 +36,7 @@ private:
char chWhile;
unsigned int startSeg;
int startPosStyling;
+ int documentVersion;
void Fill(int position) {
startPos = position - slopSize;
@@ -51,9 +55,23 @@ private:
public:
LexAccessor(IDocument *pAccess_) :
pAccess(pAccess_), startPos(extremePosition), endPos(0),
- codePage(pAccess->CodePage()), lenDoc(pAccess->Length()),
+ codePage(pAccess->CodePage()),
+ encodingType(enc8bit),
+ lenDoc(pAccess->Length()),
mask(127), validLen(0), chFlags(0), chWhile(0),
- startSeg(0), startPosStyling(0) {
+ startSeg(0), startPosStyling(0),
+ documentVersion(pAccess->Version()) {
+ switch (codePage) {
+ case 65001:
+ encodingType = encUnicode;
+ break;
+ case 932:
+ case 936:
+ case 949:
+ case 950:
+ case 1361:
+ encodingType = encDBCS;
+ }
}
char operator[](int position) {
if (position < startPos || position >= endPos) {
@@ -75,7 +93,9 @@ public:
bool IsLeadByte(char ch) {
return pAccess->IsDBCSLeadByte(ch);
}
-
+ EncodingType Encoding() const {
+ return encodingType;
+ }
bool Match(int pos, const char *s) {
for (int i=0; *s; i++) {
if (*s != SafeGetCharAt(pos+i))
@@ -93,6 +113,19 @@ public:
int LineStart(int line) {
return pAccess->LineStart(line);
}
+ int LineEnd(int line) {
+ if (documentVersion >= dvLineEnd) {
+ return (static_cast<IDocumentWithLineEnd *>(pAccess))->LineEnd(line);
+ } else {
+ // Old interface means only '\r', '\n' and '\r\n' line ends.
+ int startNext = pAccess->LineStart(line+1);
+ char chLineEnd = SafeGetCharAt(startNext-1);
+ if (chLineEnd == '\n' && (SafeGetCharAt(startNext-2) == '\r'))
+ return startNext - 2;
+ else
+ return startNext - 1;
+ }
+ }
int LevelAt(int line) {
return pAccess->GetLevel(line);
}
diff --git a/plugins/scintilla/scintilla/lexlib/LexerBase.cxx
b/plugins/scintilla/scintilla/lexlib/LexerBase.cxx
index ea5734d..bbef3f1 100644
--- a/plugins/scintilla/scintilla/lexlib/LexerBase.cxx
+++ b/plugins/scintilla/scintilla/lexlib/LexerBase.cxx
@@ -1,5 +1,5 @@
// Scintilla source code edit control
-/** @file LexerSimple.cxx
+/** @file LexerBase.cxx
** A simple lexer with no state.
**/
// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
diff --git a/plugins/scintilla/scintilla/lexlib/StyleContext.h
b/plugins/scintilla/scintilla/lexlib/StyleContext.h
index c2d223e..9f1818f 100644
--- a/plugins/scintilla/scintilla/lexlib/StyleContext.h
+++ b/plugins/scintilla/scintilla/lexlib/StyleContext.h
@@ -19,6 +19,30 @@ static inline int MakeLowerCase(int ch) {
return ch - 'A' + 'a';
}
+inline int UnicodeCodePoint(const unsigned char *us) {
+ if (us[0] < 0xC2) {
+ return us[0];
+ } else if (us[0] < 0xE0) {
+ return ((us[0] & 0x1F) << 6) + (us[1] & 0x3F);
+ } else if (us[0] < 0xF0) {
+ return ((us[0] & 0xF) << 12) + ((us[1] & 0x3F) << 6) + (us[2] & 0x3F);
+ } else if (us[0] < 0xF5) {
+ return ((us[0] & 0x7) << 18) + ((us[1] & 0x3F) << 12) + ((us[2] & 0x3F) << 6) + (us[3] &
0x3F);
+ }
+ return us[0];
+}
+
+inline int BytesInUnicodeCodePoint(int codePoint) {
+ if (codePoint < 0x80)
+ return 1;
+ else if (codePoint < 0x800)
+ return 2;
+ else if (codePoint < 0x10000)
+ return 3;
+ else
+ return 4;
+}
+
// All languages handled so far can treat all characters >= 0x80 as one class
// which just continues the current token or starts an identifier if in default.
// DBCS treated specially as the second character can be < 0x80 and hence
@@ -27,22 +51,40 @@ class StyleContext {
LexAccessor &styler;
unsigned int endPos;
StyleContext &operator=(const StyleContext &);
+
void GetNextChar(unsigned int pos) {
chNext = static_cast<unsigned char>(styler.SafeGetCharAt(pos+1));
- if (styler.IsLeadByte(static_cast<char>(chNext))) {
- chNext = chNext << 8;
- chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
+ if (styler.Encoding() == encUnicode) {
+ if (chNext >= 0x80) {
+ unsigned char bytes[4] = { static_cast<unsigned char>(chNext), 0, 0, 0 };
+ for (int trail=1; trail<3; trail++) {
+ bytes[trail] = static_cast<unsigned
char>(styler.SafeGetCharAt(pos+1+trail));
+ if (!((bytes[trail] >= 0x80) && (bytes[trail] < 0xc0))) {
+ bytes[trail] = 0;
+ break;
+ }
+ }
+ chNext = UnicodeCodePoint(bytes);
+ }
+ } else if (styler.Encoding() == encDBCS) {
+ if (styler.IsLeadByte(static_cast<char>(chNext))) {
+ chNext = chNext << 8;
+ chNext |= static_cast<unsigned char>(styler.SafeGetCharAt(pos+2));
+ }
}
// End of line?
// Trigger on CR only (Mac style) or either on LF from CR+LF (Dos/Win)
// or on LF alone (Unix). Avoid triggering two times on Dos/Win.
- atLineEnd = (ch == '\r' && chNext != '\n') ||
- (ch == '\n') ||
- (currentPos >= endPos);
+ if (lineStartNext < styler.Length())
+ atLineEnd = static_cast<int>(pos) >= (lineStartNext-1);
+ else // Last line
+ atLineEnd = static_cast<int>(pos) >= lineStartNext;
}
public:
unsigned int currentPos;
+ int currentLine;
+ int lineStartNext;
bool atLineStart;
bool atLineEnd;
int state;
@@ -55,6 +97,8 @@ public:
styler(styler_),
endPos(startPos + length),
currentPos(startPos),
+ currentLine(-1),
+ lineStartNext(-1),
atLineEnd(false),
state(initStyle & chMask), // Mask off all bits which aren't in the chMask.
chPrev(0),
@@ -62,13 +106,22 @@ public:
chNext(0) {
styler.StartAt(startPos, chMask);
styler.StartSegment(startPos);
- atLineStart = static_cast<unsigned int>(styler.LineStart(styler.GetLine(startPos))) ==
startPos;
+ currentLine = styler.GetLine(startPos);
+ lineStartNext = styler.LineStart(currentLine+1);
+ atLineStart = static_cast<unsigned int>(styler.LineStart(currentLine)) == startPos;
unsigned int pos = currentPos;
ch = static_cast<unsigned char>(styler.SafeGetCharAt(pos));
- if (styler.IsLeadByte(static_cast<char>(ch))) {
- pos++;
- ch = ch << 8;
- ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
+ if (styler.Encoding() == encUnicode) {
+ // Get the current char
+ GetNextChar(pos-1);
+ ch = chNext;
+ pos += BytesInUnicodeCodePoint(ch) - 1;
+ } else if (styler.Encoding() == encDBCS) {
+ if (styler.IsLeadByte(static_cast<char>(ch))) {
+ pos++;
+ ch = ch << 8;
+ ch |= static_cast<unsigned char>(styler.SafeGetCharAt(pos));
+ }
}
GetNextChar(pos);
}
@@ -82,12 +135,28 @@ public:
void Forward() {
if (currentPos < endPos) {
atLineStart = atLineEnd;
+ if (atLineStart) {
+ currentLine++;
+ lineStartNext = styler.LineStart(currentLine+1);
+ }
chPrev = ch;
- currentPos++;
- if (ch >= 0x100)
+ if (styler.Encoding() == encUnicode) {
+ currentPos += BytesInUnicodeCodePoint(ch);
+ } else if (styler.Encoding() == encDBCS) {
+ currentPos++;
+ if (ch >= 0x100)
+ currentPos++;
+ } else {
currentPos++;
+ }
ch = chNext;
- GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0));
+ if (styler.Encoding() == encUnicode) {
+ GetNextChar(currentPos + BytesInUnicodeCodePoint(ch)-1);
+ } else if (styler.Encoding() == encDBCS) {
+ GetNextChar(currentPos + ((ch >= 0x100) ? 1 : 0));
+ } else {
+ GetNextChar(currentPos);
+ }
} else {
atLineStart = false;
chPrev = ' ';
diff --git a/plugins/scintilla/scintilla/lexlib/SubStyles.h b/plugins/scintilla/scintilla/lexlib/SubStyles.h
new file mode 100644
index 0000000..e6c34e0
--- /dev/null
+++ b/plugins/scintilla/scintilla/lexlib/SubStyles.h
@@ -0,0 +1,162 @@
+// Scintilla source code edit control
+/** @file SubStyles.h
+ ** Manage substyles for a lexer.
+ **/
+// Copyright 2012 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SUBSTYLES_H
+#define SUBSTYLES_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class WordClassifier {
+ int firstStyle;
+ int lenStyles;
+ std::map<std::string, int> wordToStyle;
+
+public:
+
+ WordClassifier() : firstStyle(0), lenStyles(0) {
+ }
+
+ void Allocate(int firstStyle_, int lenStyles_) {
+ firstStyle = firstStyle_;
+ lenStyles = lenStyles_;
+ wordToStyle.clear();
+ }
+
+ int Start() const {
+ return firstStyle;
+ }
+
+ int Length() const {
+ return lenStyles;
+ }
+
+ void Clear() {
+ firstStyle = 0;
+ lenStyles = 0;
+ wordToStyle.clear();
+ }
+
+ int ValueFor(const std::string &s) const {
+ std::map<std::string, int>::const_iterator it = wordToStyle.find(s);
+ if (it != wordToStyle.end())
+ return it->second;
+ else
+ return -1;
+ }
+
+ bool IncludesStyle(int style) const {
+ return (style >= firstStyle) && (style < (firstStyle + lenStyles));
+ }
+
+ void SetIdentifiers(int style, const char *identifiers) {
+ while (*identifiers) {
+ const char *cpSpace = identifiers;
+ while (*cpSpace && *cpSpace != ' ')
+ cpSpace++;
+ std::string word(identifiers, cpSpace - identifiers);
+ wordToStyle[word] = style;
+ identifiers = cpSpace;
+ if (*identifiers)
+ identifiers++;
+ }
+ }
+};
+
+class SubStyles {
+ int classifications;
+ const char *baseStyles;
+ int styleFirst;
+ int stylesAvailable;
+ int secondaryDistance;
+ int allocated;
+ std::vector<WordClassifier> classifiers;
+
+ int BlockFromBaseStyle(int baseStyle) const {
+ for (int b=0; b < classifications; b++) {
+ if (baseStyle == baseStyles[b])
+ return b;
+ }
+ return -1;
+ }
+
+ int BlockFromStyle(int style) const {
+ int b = 0;
+ for (std::vector<WordClassifier>::const_iterator it=classifiers.begin(); it !=
classifiers.end(); ++it) {
+ if (it->IncludesStyle(style))
+ return b;
+ b++;
+ }
+ return -1;
+ }
+
+public:
+
+ SubStyles(const char *baseStyles_, int styleFirst_, int stylesAvailable_, int secondaryDistance_) :
+ classifications(0),
+ baseStyles(baseStyles_),
+ styleFirst(styleFirst_),
+ stylesAvailable(stylesAvailable_),
+ secondaryDistance(secondaryDistance_),
+ allocated(0) {
+ while (baseStyles[classifications]) {
+ classifications++;
+ classifiers.push_back(WordClassifier());
+ }
+ }
+
+ int Allocate(int styleBase, int numberStyles) {
+ int block = BlockFromBaseStyle(styleBase);
+ if (block >= 0) {
+ if ((allocated + numberStyles) > stylesAvailable)
+ return -1;
+ int startBlock = styleFirst + allocated;
+ allocated += numberStyles;
+ classifiers[block].Allocate(startBlock, numberStyles);
+ return startBlock;
+ } else {
+ return -1;
+ }
+ }
+
+ int Start(int styleBase) {
+ int block = BlockFromBaseStyle(styleBase);
+ return (block >= 0) ? classifiers[block].Start() : -1;
+ }
+
+ int Length(int styleBase) {
+ int block = BlockFromBaseStyle(styleBase);
+ return (block >= 0) ? classifiers[block].Length() : 0;
+ }
+
+ int DistanceToSecondaryStyles() const {
+ return secondaryDistance;
+ }
+
+ void SetIdentifiers(int style, const char *identifiers) {
+ int block = BlockFromStyle(style);
+ if (block >= 0)
+ classifiers[block].SetIdentifiers(style, identifiers);
+ }
+
+ void Free() {
+ allocated = 0;
+ for (std::vector<WordClassifier>::iterator it=classifiers.begin(); it != classifiers.end();
++it)
+ it->Clear();
+ }
+
+ const WordClassifier &Classifier(int baseStyle) const {
+ return classifiers[BlockFromBaseStyle(baseStyle)];
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/src/AutoComplete.cxx
b/plugins/scintilla/scintilla/src/AutoComplete.cxx
index aa65810..bab123a 100644
--- a/plugins/scintilla/scintilla/src/AutoComplete.cxx
+++ b/plugins/scintilla/scintilla/src/AutoComplete.cxx
@@ -10,6 +10,8 @@
#include <stdio.h>
#include <assert.h>
+#include <string>
+
#include "Platform.h"
#include "CharacterSet.h"
@@ -32,7 +34,9 @@ AutoComplete::AutoComplete() :
cancelAtStartPos(true),
autoHide(true),
dropRestOfWord(false),
- ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE) {
+ ignoreCaseBehaviour(SC_CASEINSENSITIVEBEHAVIOUR_RESPECTCASE),
+ widthLBDefault(100),
+ heightLBDefault(100) {
lb = ListBox::Allocate();
stopChars[0] = '\0';
fillUpChars[0] = '\0';
@@ -101,6 +105,16 @@ void AutoComplete::SetList(const char *list) {
lb->SetList(list, separator, typesep);
}
+int AutoComplete::GetSelection() const {
+ return lb->GetSelection();
+}
+
+std::string AutoComplete::GetValue(int item) const {
+ char value[maxItemLen];
+ lb->GetValue(item, value, sizeof(value));
+ return std::string(value);
+}
+
void AutoComplete::Show(bool show) {
lb->Show(show);
if (show)
@@ -130,7 +144,6 @@ void AutoComplete::Move(int delta) {
void AutoComplete::Select(const char *word) {
size_t lenWord = strlen(word);
int location = -1;
- const int maxItemLen=1000;
int start = 0; // lower bound of the api array block to search
int end = lb->Length() - 1; // upper bound of the api array block to search
while ((start <= end) && (location == -1)) { // Binary searching loop
diff --git a/plugins/scintilla/scintilla/src/AutoComplete.h b/plugins/scintilla/scintilla/src/AutoComplete.h
index 19a1271..4d27e6a 100644
--- a/plugins/scintilla/scintilla/src/AutoComplete.h
+++ b/plugins/scintilla/scintilla/src/AutoComplete.h
@@ -20,8 +20,10 @@ class AutoComplete {
char fillUpChars[256];
char separator;
char typesep; // Type seperator
+ enum { maxItemLen=1000 };
public:
+
bool ignoreCase;
bool chooseSingle;
ListBox *lb;
@@ -32,6 +34,8 @@ public:
bool autoHide;
bool dropRestOfWord;
unsigned int ignoreCaseBehaviour;
+ int widthLBDefault;
+ int heightLBDefault;
AutoComplete();
~AutoComplete();
@@ -61,6 +65,12 @@ public:
/// The list string contains a sequence of words separated by the separator character
void SetList(const char *list);
+
+ /// Return the position of the currently selected list item
+ int GetSelection() const;
+
+ /// Return the value of an item in the list
+ std::string GetValue(int item) const;
void Show(bool show);
void Cancel();
diff --git a/plugins/scintilla/scintilla/src/CallTip.cxx b/plugins/scintilla/scintilla/src/CallTip.cxx
index d93d804..d5ba3bd 100644
--- a/plugins/scintilla/scintilla/src/CallTip.cxx
+++ b/plugins/scintilla/scintilla/src/CallTip.cxx
@@ -18,9 +18,6 @@
using namespace Scintilla;
#endif
-static const int insetX = 5; // text inset in x from calltip border
-static const int widthArrow = 14;
-
CallTip::CallTip() {
wCallTip = 0;
inCallTipMode = false;
@@ -36,6 +33,11 @@ CallTip::CallTip() {
above = false;
useStyleCallTip = false; // for backwards compatibility
+ insetX = 5;
+ widthArrow = 14;
+ borderHeight = 2; // Extra line for border and an empty line at top and bottom.
+ verticalOffset = 1;
+
#ifdef __APPLE__
// proper apple colours for the default
colourBG = ColourDesired(0xff, 0xff, 0xc6);
@@ -284,15 +286,15 @@ PRectangle CallTip::CallTipStart(int pos, Point pt, int textHeight, const char *
}
lineHeight = surfaceMeasure->Height(font);
- // Extra line for border and an empty line at top and bottom. The returned
+ // The returned
// rectangle is aligned to the right edge of the last arrow encountered in
// the tip text, else to the tip text left edge.
- int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + 2 + 2;
+ int height = lineHeight * numLines - surfaceMeasure->InternalLeading(font) + borderHeight * 2;
delete surfaceMeasure;
if (above) {
- return PRectangle(pt.x - offsetMain, pt.y - 1 - height, pt.x + width - offsetMain, pt.y - 1);
+ return PRectangle(pt.x - offsetMain, pt.y - verticalOffset - height, pt.x + width -
offsetMain, pt.y - verticalOffset);
} else {
- return PRectangle(pt.x - offsetMain, pt.y + 1 + textHeight, pt.x + width - offsetMain, pt.y +
1 + textHeight + height);
+ return PRectangle(pt.x - offsetMain, pt.y + verticalOffset + textHeight, pt.x + width -
offsetMain, pt.y + verticalOffset + textHeight + height);
}
}
@@ -307,7 +309,7 @@ void CallTip::SetHighlight(int start, int end) {
// Avoid flashing by checking something has really changed
if ((start != startHighlight) || (end != endHighlight)) {
startHighlight = start;
- endHighlight = end;
+ endHighlight = (end > start) ? end : start;
if (wCallTip.Created()) {
wCallTip.InvalidateAll();
}
diff --git a/plugins/scintilla/scintilla/src/CallTip.h b/plugins/scintilla/scintilla/src/CallTip.h
index 657e0ca..fdc4db8 100644
--- a/plugins/scintilla/scintilla/src/CallTip.h
+++ b/plugins/scintilla/scintilla/src/CallTip.h
@@ -50,6 +50,11 @@ public:
int codePage;
int clickPlace;
+ int insetX; // text inset in x from calltip border
+ int widthArrow;
+ int borderHeight;
+ int verticalOffset; // pixel offset up or down of the calltip with respect to the line
+
CallTip();
~CallTip();
diff --git a/plugins/scintilla/scintilla/src/Catalogue.cxx b/plugins/scintilla/scintilla/src/Catalogue.cxx
index 2f75247..cd69d81 100644
--- a/plugins/scintilla/scintilla/src/Catalogue.cxx
+++ b/plugins/scintilla/scintilla/src/Catalogue.cxx
@@ -152,7 +152,7 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmPerl);
LINK_LEXER(lmPHPSCRIPT);
LINK_LEXER(lmPLM);
- LINK_LEXER(lmPo);
+ LINK_LEXER(lmPO);
LINK_LEXER(lmPOV);
LINK_LEXER(lmPowerPro);
LINK_LEXER(lmPowerShell);
diff --git a/plugins/scintilla/scintilla/src/CellBuffer.cxx b/plugins/scintilla/scintilla/src/CellBuffer.cxx
index 11b8b4a..872616c 100644
--- a/plugins/scintilla/scintilla/src/CellBuffer.cxx
+++ b/plugins/scintilla/scintilla/src/CellBuffer.cxx
@@ -16,6 +16,7 @@
#include "SplitVector.h"
#include "Partitioning.h"
#include "CellBuffer.h"
+#include "UniConversion.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -331,6 +332,7 @@ void UndoHistory::CompletedRedoStep() {
CellBuffer::CellBuffer() {
readOnly = false;
+ utf8LineEnds = 0;
collectingUndo = true;
}
@@ -458,6 +460,13 @@ void CellBuffer::Allocate(int newSize) {
style.ReAllocate(newSize);
}
+void CellBuffer::SetLineEndTypes(int utf8LineEnds_) {
+ if (utf8LineEnds != utf8LineEnds_) {
+ utf8LineEnds = utf8LineEnds_;
+ ResetLineEnds();
+ }
+}
+
void CellBuffer::SetPerLine(PerLine *pl) {
lv.SetPerLine(pl);
}
@@ -501,11 +510,63 @@ void CellBuffer::RemoveLine(int line) {
lv.RemoveLine(line);
}
+bool CellBuffer::UTF8LineEndOverlaps(int position) const {
+ unsigned char bytes[] = {
+ static_cast<unsigned char>(substance.ValueAt(position-2)),
+ static_cast<unsigned char>(substance.ValueAt(position-1)),
+ static_cast<unsigned char>(substance.ValueAt(position)),
+ static_cast<unsigned char>(substance.ValueAt(position+1)),
+ };
+ return UTF8IsSeparator(bytes) || UTF8IsSeparator(bytes+1) || UTF8IsNEL(bytes+1);
+}
+
+void CellBuffer::ResetLineEnds() {
+ // Reinitialize line data -- too much work to preserve
+ lv.Init();
+
+ int position = 0;
+ int length = Length();
+ int lineInsert = 1;
+ bool atLineStart = true;
+ lv.InsertText(lineInsert-1, length);
+ unsigned char chBeforePrev = 0;
+ unsigned char chPrev = 0;
+ for (int i = 0; i < length; i++) {
+ unsigned char ch = substance.ValueAt(position + i);
+ if (ch == '\r') {
+ InsertLine(lineInsert, (position + i) + 1, atLineStart);
+ lineInsert++;
+ } else if (ch == '\n') {
+ if (chPrev == '\r') {
+ // Patch up what was end of line
+ lv.SetLineStart(lineInsert - 1, (position + i) + 1);
+ } else {
+ InsertLine(lineInsert, (position + i) + 1, atLineStart);
+ lineInsert++;
+ }
+ } else if (utf8LineEnds) {
+ unsigned char back3[3] = {chBeforePrev, chPrev, ch};
+ if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) {
+ InsertLine(lineInsert, (position + i) + 1, atLineStart);
+ lineInsert++;
+ }
+ }
+ chBeforePrev = chPrev;
+ chPrev = ch;
+ }
+}
+
void CellBuffer::BasicInsertString(int position, const char *s, int insertLength) {
if (insertLength == 0)
return;
PLATFORM_ASSERT(insertLength > 0);
+ unsigned char chAfter = substance.ValueAt(position);
+ bool breakingUTF8LineEnd = false;
+ if (utf8LineEnds && UTF8IsTrailByte(chAfter)) {
+ breakingUTF8LineEnd = UTF8LineEndOverlaps(position);
+ }
+
substance.InsertFromArray(position, s, 0, insertLength);
style.InsertValue(position, insertLength, 0);
@@ -513,14 +574,17 @@ void CellBuffer::BasicInsertString(int position, const char *s, int insertLength
bool atLineStart = lv.LineStart(lineInsert-1) == position;
// Point all the lines after the insertion point further along in the buffer
lv.InsertText(lineInsert-1, insertLength);
- char chPrev = substance.ValueAt(position - 1);
- char chAfter = substance.ValueAt(position + insertLength);
+ unsigned char chBeforePrev = substance.ValueAt(position - 2);
+ unsigned char chPrev = substance.ValueAt(position - 1);
if (chPrev == '\r' && chAfter == '\n') {
// Splitting up a crlf pair at position
InsertLine(lineInsert, position, false);
lineInsert++;
}
- char ch = ' ';
+ if (breakingUTF8LineEnd) {
+ RemoveLine(lineInsert);
+ }
+ unsigned char ch = ' ';
for (int i = 0; i < insertLength; i++) {
ch = s[i];
if (ch == '\r') {
@@ -534,7 +598,14 @@ void CellBuffer::BasicInsertString(int position, const char *s, int insertLength
InsertLine(lineInsert, (position + i) + 1, atLineStart);
lineInsert++;
}
+ } else if (utf8LineEnds) {
+ unsigned char back3[3] = {chBeforePrev, chPrev, ch};
+ if (UTF8IsSeparator(back3) || UTF8IsNEL(back3+1)) {
+ InsertLine(lineInsert, (position + i) + 1, atLineStart);
+ lineInsert++;
+ }
}
+ chBeforePrev = chPrev;
chPrev = ch;
}
// Joining two lines where last insertion is cr and following substance starts with lf
@@ -543,6 +614,22 @@ void CellBuffer::BasicInsertString(int position, const char *s, int insertLength
// End of line already in buffer so drop the newly created one
RemoveLine(lineInsert - 1);
}
+ } else if (utf8LineEnds && !UTF8IsAscii(chAfter)) {
+ // May have end of UTF-8 line end in buffer and start in insertion
+ for (int j = 0; j < UTF8SeparatorLength-1; j++) {
+ unsigned char chAt = substance.ValueAt(position + insertLength + j);
+ unsigned char back3[3] = {chBeforePrev, chPrev, chAt};
+ if (UTF8IsSeparator(back3)) {
+ InsertLine(lineInsert, (position + insertLength + j) + 1, atLineStart);
+ lineInsert++;
+ }
+ if ((j == 0) && UTF8IsNEL(back3+1)) {
+ InsertLine(lineInsert, (position + insertLength + j) + 1, atLineStart);
+ lineInsert++;
+ }
+ chBeforePrev = chPrev;
+ chPrev = chAt;
+ }
}
}
@@ -560,9 +647,9 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) {
int lineRemove = lv.LineFromPosition(position) + 1;
lv.InsertText(lineRemove-1, - (deleteLength));
- char chPrev = substance.ValueAt(position - 1);
- char chBefore = chPrev;
- char chNext = substance.ValueAt(position);
+ unsigned char chPrev = substance.ValueAt(position - 1);
+ unsigned char chBefore = chPrev;
+ unsigned char chNext = substance.ValueAt(position);
bool ignoreNL = false;
if (chPrev == '\r' && chNext == '\n') {
// Move back one
@@ -570,8 +657,13 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) {
lineRemove++;
ignoreNL = true; // First \n is not real deletion
}
+ if (utf8LineEnds && UTF8IsTrailByte(chNext)) {
+ if (UTF8LineEndOverlaps(position)) {
+ RemoveLine(lineRemove);
+ }
+ }
- char ch = chNext;
+ unsigned char ch = chNext;
for (int i = 0; i < deleteLength; i++) {
chNext = substance.ValueAt(position + i + 1);
if (ch == '\r') {
@@ -584,6 +676,14 @@ void CellBuffer::BasicDeleteChars(int position, int deleteLength) {
} else {
RemoveLine(lineRemove);
}
+ } else if (utf8LineEnds) {
+ if (!UTF8IsAscii(ch)) {
+ unsigned char next3[3] = {ch, chNext,
+ static_cast<unsigned char>(substance.ValueAt(position + i +
2))};
+ if (UTF8IsSeparator(next3) || UTF8IsNEL(next3)) {
+ RemoveLine(lineRemove);
+ }
+ }
}
ch = chNext;
diff --git a/plugins/scintilla/scintilla/src/CellBuffer.h b/plugins/scintilla/scintilla/src/CellBuffer.h
index 388b902..cde6f5a 100644
--- a/plugins/scintilla/scintilla/src/CellBuffer.h
+++ b/plugins/scintilla/scintilla/src/CellBuffer.h
@@ -98,6 +98,9 @@ class UndoHistory {
void EnsureUndoRoom();
+ // Private so UndoHistory objects can not be copied
+ UndoHistory(const UndoHistory &);
+
public:
UndoHistory();
~UndoHistory();
@@ -136,12 +139,15 @@ private:
SplitVector<char> substance;
SplitVector<char> style;
bool readOnly;
+ int utf8LineEnds;
bool collectingUndo;
UndoHistory uh;
LineVector lv;
+ bool UTF8LineEndOverlaps(int position) const;
+ void ResetLineEnds();
/// Actions without undo
void BasicInsertString(int position, const char *s, int insertLength);
void BasicDeleteChars(int position, int deleteLength);
@@ -162,6 +168,8 @@ public:
int Length() const;
void Allocate(int newSize);
+ int GetLineEndTypes() const { return utf8LineEnds; }
+ void SetLineEndTypes(int utf8LineEnds_);
void SetPerLine(PerLine *pl);
int Lines() const;
int LineStart(int line) const;
diff --git a/plugins/scintilla/scintilla/src/CharClassify.cxx
b/plugins/scintilla/scintilla/src/CharClassify.cxx
index c16af45..7e3db73 100644
--- a/plugins/scintilla/scintilla/src/CharClassify.cxx
+++ b/plugins/scintilla/scintilla/src/CharClassify.cxx
@@ -46,3 +46,19 @@ void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) {
}
}
}
+
+int CharClassify::GetCharsOfClass(cc characterClass, unsigned char *buffer) {
+ // Get characters belonging to the given char class; return the number
+ // of characters (if the buffer is NULL, don't write to it).
+ int count = 0;
+ for (int ch = maxChar - 1; ch >= 0; --ch) {
+ if (charClass[ch] == characterClass) {
+ ++count;
+ if (buffer) {
+ *buffer = static_cast<unsigned char>(ch);
+ buffer++;
+ }
+ }
+ }
+ return count;
+}
diff --git a/plugins/scintilla/scintilla/src/CharClassify.h b/plugins/scintilla/scintilla/src/CharClassify.h
index e8b798e..5d2734c 100644
--- a/plugins/scintilla/scintilla/src/CharClassify.h
+++ b/plugins/scintilla/scintilla/src/CharClassify.h
@@ -19,6 +19,7 @@ public:
enum cc { ccSpace, ccNewLine, ccWord, ccPunctuation };
void SetDefaultCharClasses(bool includeWordClass);
void SetCharClasses(const unsigned char *chars, cc newCharClass);
+ int GetCharsOfClass(cc charClass, unsigned char *buffer);
cc GetClass(unsigned char ch) const { return static_cast<cc>(charClass[ch]);}
bool IsWord(unsigned char ch) const { return static_cast<cc>(charClass[ch]) == ccWord;}
diff --git a/plugins/scintilla/scintilla/src/ContractionState.cxx
b/plugins/scintilla/scintilla/src/ContractionState.cxx
index af0f4f3..957fd17 100644
--- a/plugins/scintilla/scintilla/src/ContractionState.cxx
+++ b/plugins/scintilla/scintilla/src/ContractionState.cxx
@@ -66,7 +66,7 @@ int ContractionState::LinesDisplayed() const {
int ContractionState::DisplayFromDoc(int lineDoc) const {
if (OneToOne()) {
- return lineDoc;
+ return (lineDoc <= linesInDocument) ? lineDoc : linesInDocument;
} else {
if (lineDoc > displayLines->Partitions())
lineDoc = displayLines->Partitions();
diff --git a/plugins/scintilla/scintilla/src/Document.cxx b/plugins/scintilla/scintilla/src/Document.cxx
index 244e96e..b75c754 100644
--- a/plugins/scintilla/scintilla/src/Document.cxx
+++ b/plugins/scintilla/scintilla/src/Document.cxx
@@ -35,27 +35,10 @@
using namespace Scintilla;
#endif
-// This is ASCII specific but is safe with chars >= 0x80
-static inline bool isspacechar(unsigned char ch) {
- return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
-}
-
static inline bool IsPunctuation(char ch) {
return isascii(ch) && ispunct(ch);
}
-static inline bool IsADigit(char ch) {
- return isascii(ch) && isdigit(ch);
-}
-
-static inline bool IsLowerCase(char ch) {
- return isascii(ch) && islower(ch);
-}
-
-static inline bool IsUpperCase(char ch) {
- return isascii(ch) && isupper(ch);
-}
-
void LexInterface::Colourise(int start, int end) {
if (pdoc && instance && !performingStyle) {
// Protect against reentrance, which may occur, for example, when
@@ -84,14 +67,27 @@ void LexInterface::Colourise(int start, int end) {
}
}
+int LexInterface::LineEndTypesSupported() {
+ if (instance) {
+ int interfaceVersion = instance->Version();
+ if (interfaceVersion >= lvSubStyles) {
+ ILexerWithSubStyles *ssinstance = static_cast<ILexerWithSubStyles *>(instance);
+ return ssinstance->LineEndTypesSupported();
+ }
+ }
+ return 0;
+}
+
Document::Document() {
refCount = 0;
+ pcf = NULL;
#ifdef _WIN32
eolMode = SC_EOL_CRLF;
#else
eolMode = SC_EOL_LF;
#endif
dbcsCodePage = 0;
+ lineEndBitSet = SC_LINE_END_TYPE_DEFAULT;
stylingBits = 5;
stylingBitsMask = 0x1F;
stylingMask = 0;
@@ -140,6 +136,8 @@ Document::~Document() {
regex = 0;
delete pli;
pli = 0;
+ delete pcf;
+ pcf = 0;
}
void Document::Init() {
@@ -149,6 +147,40 @@ void Document::Init() {
}
}
+int Document::LineEndTypesSupported() const {
+ if ((SC_CP_UTF8 == dbcsCodePage) && pli)
+ return pli->LineEndTypesSupported();
+ else
+ return 0;
+}
+
+bool Document::SetDBCSCodePage(int dbcsCodePage_) {
+ if (dbcsCodePage != dbcsCodePage_) {
+ dbcsCodePage = dbcsCodePage_;
+ SetCaseFolder(NULL);
+ cb.SetLineEndTypes(lineEndBitSet & LineEndTypesSupported());
+ return true;
+ } else {
+ return false;
+ }
+}
+
+bool Document::SetLineEndTypesAllowed(int lineEndBitSet_) {
+ if (lineEndBitSet != lineEndBitSet_) {
+ lineEndBitSet = lineEndBitSet_;
+ int lineEndBitSetActive = lineEndBitSet & LineEndTypesSupported();
+ if (lineEndBitSetActive != cb.GetLineEndTypes()) {
+ ModifiedAt(0);
+ cb.SetLineEndTypes(lineEndBitSetActive);
+ return true;
+ } else {
+ return false;
+ }
+ } else {
+ return false;
+ }
+}
+
void Document::InsertLine(int line) {
for (int j=0; j<ldSize; j++) {
if (perLineData[j])
@@ -249,11 +281,25 @@ int SCI_METHOD Document::LineStart(int line) const {
return cb.LineStart(line);
}
-int Document::LineEnd(int line) const {
+int SCI_METHOD Document::LineEnd(int line) const {
if (line == LinesTotal() - 1) {
return LineStart(line + 1);
} else {
- int position = LineStart(line + 1) - 1;
+ int position = LineStart(line + 1);
+ if (SC_CP_UTF8 == dbcsCodePage) {
+ unsigned char bytes[] = {
+ static_cast<unsigned char>(cb.CharAt(position-3)),
+ static_cast<unsigned char>(cb.CharAt(position-2)),
+ static_cast<unsigned char>(cb.CharAt(position-1)),
+ };
+ if (UTF8IsSeparator(bytes)) {
+ return position - UTF8SeparatorLength;
+ }
+ if (UTF8IsNEL(bytes+1)) {
+ return position - UTF8NELLength;
+ }
+ }
+ position--; // Back over CR or LF
// When line terminator is CR+LF, may need to go back one more
if ((position > LineStart(line)) && (cb.CharAt(position - 1) == '\r')) {
position--;
@@ -281,6 +327,10 @@ bool Document::IsLineEndPosition(int position) const {
return LineEnd(LineFromPosition(position)) == position;
}
+bool Document::IsPositionInLineEnd(int position) const {
+ return position >= LineEnd(LineFromPosition(position));
+}
+
int Document::VCHomePosition(int position) const {
int line = LineFromPosition(position);
int startPosition = LineStart(line);
@@ -751,7 +801,7 @@ void Document::CheckReadOnly() {
// SetStyleAt does not change the persistent state of a document
bool Document::DeleteChars(int pos, int len) {
- if (len == 0)
+ if (len <= 0)
return false;
if ((pos + len) > Length())
return false;
@@ -849,6 +899,10 @@ int Document::Undo() {
bool multiLine = false;
int steps = cb.StartUndo();
//Platform::DebugPrintf("Steps=%d\n", steps);
+ int coalescedRemovePos = -1;
+ int coalescedRemoveLen = 0;
+ int prevRemoveActionPos = -1;
+ int prevRemoveActionLen = 0;
for (int step = 0; step < steps; step++) {
const int prevLinesTotal = LinesTotal();
const Action &action = cb.GetUndoStep();
@@ -859,15 +913,20 @@ int Document::Undo() {
DocModification dm(SC_MOD_CONTAINER | SC_PERFORMED_UNDO);
dm.token = action.position;
NotifyModified(dm);
+ if (!action.mayCoalesce) {
+ coalescedRemovePos = -1;
+ coalescedRemoveLen = 0;
+ prevRemoveActionPos = -1;
+ prevRemoveActionLen = 0;
+ }
} else {
NotifyModified(DocModification(
SC_MOD_BEFOREDELETE |
SC_PERFORMED_UNDO, action));
}
cb.PerformUndoStep();
- int cellPosition = action.position;
if (action.at != containerAction) {
- ModifiedAt(cellPosition);
- newPos = cellPosition;
+ ModifiedAt(action.position);
+ newPos = action.position;
}
int modFlags = SC_PERFORMED_UNDO;
@@ -875,8 +934,22 @@ int Document::Undo() {
if (action.at == removeAction) {
newPos += action.lenData;
modFlags |= SC_MOD_INSERTTEXT;
+ if ((coalescedRemoveLen > 0) &&
+ (action.position == prevRemoveActionPos || action.position ==
(prevRemoveActionPos + prevRemoveActionLen))) {
+ coalescedRemoveLen += action.lenData;
+ newPos = coalescedRemovePos + coalescedRemoveLen;
+ } else {
+ coalescedRemovePos = action.position;
+ coalescedRemoveLen = action.lenData;
+ }
+ prevRemoveActionPos = action.position;
+ prevRemoveActionLen = action.lenData;
} else if (action.at == insertAction) {
modFlags |= SC_MOD_DELETETEXT;
+ coalescedRemovePos = -1;
+ coalescedRemoveLen = 0;
+ prevRemoveActionPos = -1;
+ prevRemoveActionLen = 0;
}
if (steps > 1)
modFlags |= SC_MULTISTEPUNDOREDO;
@@ -888,7 +961,7 @@ int Document::Undo() {
if (multiLine)
modFlags |= SC_MULTILINEUNDOREDO;
}
- NotifyModified(DocModification(modFlags, cellPosition, action.lenData,
+ NotifyModified(DocModification(modFlags, action.position, action.lenData,
linesAdded,
action.data));
}
@@ -1003,21 +1076,19 @@ static int NextTab(int pos, int tabSize) {
return ((pos / tabSize) + 1) * tabSize;
}
-static void CreateIndentation(char *linebuf, int length, int indent, int tabSize, bool insertSpaces) {
- length--; // ensure space for \0
+static std::string CreateIndentation(int indent, int tabSize, bool insertSpaces) {
+ std::string indentation;
if (!insertSpaces) {
- while ((indent >= tabSize) && (length > 0)) {
- *linebuf++ = '\t';
+ while (indent >= tabSize) {
+ indentation += '\t';
indent -= tabSize;
- length--;
}
}
- while ((indent > 0) && (length > 0)) {
- *linebuf++ = ' ';
+ while (indent > 0) {
+ indentation += ' ';
indent--;
- length--;
}
- *linebuf = '\0';
+ return indentation;
}
int SCI_METHOD Document::GetLineIndentation(int line) {
@@ -1043,13 +1114,12 @@ void Document::SetLineIndentation(int line, int indent) {
if (indent < 0)
indent = 0;
if (indent != indentOfLine) {
- char linebuf[1000];
- CreateIndentation(linebuf, sizeof(linebuf), indent, tabInChars, !useTabs);
+ std::string linebuf = CreateIndentation(indent, tabInChars, !useTabs);
int thisLineStart = LineStart(line);
int indentPos = GetLineIndentPosition(line);
UndoGroup ug(this);
DeleteChars(thisLineStart, indentPos - thisLineStart);
- InsertCString(thisLineStart, linebuf);
+ InsertCString(thisLineStart, linebuf.c_str());
}
}
@@ -1416,6 +1486,15 @@ bool Document::MatchesWordOptions(bool word, bool wordStart, int pos, int length
(wordStart && IsWordStartAt(pos));
}
+bool Document::HasCaseFolder(void) const {
+ return pcf != 0;
+}
+
+void Document::SetCaseFolder(CaseFolder *pcf_) {
+ delete pcf;
+ pcf = pcf_;
+}
+
/**
* Find text in document, supporting both forward and backward
* searches (just pass minPos > maxPos to do a backward search)
@@ -1423,7 +1502,7 @@ bool Document::MatchesWordOptions(bool word, bool wordStart, int pos, int length
*/
long Document::FindText(int minPos, int maxPos, const char *search,
bool caseSensitive, bool word, bool wordStart, bool regExp, int flags,
- int *length, CaseFolder *pcf) {
+ int *length) {
if (*length <= 0)
return minPos;
if (regExp) {
@@ -1615,6 +1694,10 @@ void Document::SetCharClasses(const unsigned char *chars, CharClassify::cc newCh
charClass.SetCharClasses(chars, newCharClass);
}
+int Document::GetCharsOfClass(CharClassify::cc characterClass, unsigned char *buffer) {
+ return charClass.GetCharsOfClass(characterClass, buffer);
+}
+
void Document::SetStylingBits(int bits) {
stylingBits = bits;
stylingBitsMask = (1 << stylingBits) - 1;
@@ -1730,10 +1813,12 @@ void Document::MarginSetText(int line, const char *text) {
void Document::MarginSetStyle(int line, int style) {
static_cast<LineAnnotation *>(perLineData[ldMargin])->SetStyle(line, style);
+ NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line));
}
void Document::MarginSetStyles(int line, const unsigned char *styles) {
static_cast<LineAnnotation *>(perLineData[ldMargin])->SetStyles(line, styles);
+ NotifyModified(DocModification(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line));
}
int Document::MarginLength(int line) const {
diff --git a/plugins/scintilla/scintilla/src/Document.h b/plugins/scintilla/scintilla/src/Document.h
index 7e03f3d..16804d3 100644
--- a/plugins/scintilla/scintilla/src/Document.h
+++ b/plugins/scintilla/scintilla/src/Document.h
@@ -186,6 +186,7 @@ public:
virtual ~LexInterface() {
}
void Colourise(int start, int end);
+ int LineEndTypesSupported();
bool UseContainerLexing() const {
return instance == 0;
}
@@ -193,7 +194,7 @@ public:
/**
*/
-class Document : PerLine, public IDocument, public ILoader {
+class Document : PerLine, public IDocumentWithLineEnd, public ILoader {
public:
/** Used to pair watcher pointer with user data. */
@@ -212,6 +213,7 @@ private:
int refCount;
CellBuffer cb;
CharClassify charClass;
+ CaseFolder *pcf;
char stylingMask;
int endStyled;
int styleClock;
@@ -239,6 +241,7 @@ public:
int eolMode;
/// Can also be SC_CP_UTF8 to enable UTF-8 mode
int dbcsCodePage;
+ int lineEndBitSet;
int tabInChars;
int indentInChars;
int actualIndentInChars;
@@ -255,11 +258,16 @@ public:
int SCI_METHOD Release();
virtual void Init();
+ int LineEndTypesSupported() const;
+ bool SetDBCSCodePage(int dbcsCodePage_);
+ int GetLineEndTypesAllowed() { return cb.GetLineEndTypes(); }
+ bool SetLineEndTypesAllowed(int lineEndBitSet_);
+ int GetLineEndTypesActive() { return cb.GetLineEndTypes(); }
virtual void InsertLine(int line);
virtual void RemoveLine(int line);
int SCI_METHOD Version() const {
- return dvOriginal;
+ return dvLineEnd;
}
void SCI_METHOD SetErrorStatus(int status);
@@ -336,9 +344,10 @@ public:
void DeleteAllMarks(int markerNum);
int LineFromHandle(int markerHandle);
int SCI_METHOD LineStart(int line) const;
- int LineEnd(int line) const;
+ int SCI_METHOD LineEnd(int line) const;
int LineEndPosition(int position) const;
bool IsLineEndPosition(int position) const;
+ bool IsPositionInLineEnd(int position) const;
int VCHomePosition(int position) const;
int SCI_METHOD SetLevel(int line, int level);
@@ -355,8 +364,10 @@ public:
int SCI_METHOD Length() const { return cb.Length(); }
void Allocate(int newSize) { cb.Allocate(newSize); }
bool MatchesWordOptions(bool word, bool wordStart, int pos, int length);
+ bool HasCaseFolder(void) const;
+ void SetCaseFolder(CaseFolder *pcf_);
long FindText(int minPos, int maxPos, const char *search, bool caseSensitive, bool word,
- bool wordStart, bool regExp, int flags, int *length, CaseFolder *pcf);
+ bool wordStart, bool regExp, int flags, int *length);
const char *SubstituteByPosition(const char *text, int *length);
int LinesTotal() const;
@@ -364,6 +375,7 @@ public:
void SetDefaultCharClasses(bool includeWordClass);
void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass);
+ int GetCharsOfClass(CharClassify::cc charClass, unsigned char *buffer);
void SetStylingBits(int bits);
void SCI_METHOD StartStyling(int position, char mask);
bool SCI_METHOD SetStyleFor(int length, char style);
diff --git a/plugins/scintilla/scintilla/src/Editor.cxx b/plugins/scintilla/scintilla/src/Editor.cxx
index d72ff30..d02f095 100644
--- a/plugins/scintilla/scintilla/src/Editor.cxx
+++ b/plugins/scintilla/scintilla/src/Editor.cxx
@@ -9,6 +9,7 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <math.h>
#include <assert.h>
#include <string>
@@ -104,6 +105,7 @@ Editor::Editor() {
stylesValid = false;
technology = SC_TECHNOLOGY_DEFAULT;
+ scaleRGBAImage = 100;
printMagnification = 0;
printColourMode = SC_PRINT_NORMAL;
@@ -173,6 +175,7 @@ Editor::Editor() {
pixmapLine = 0;
pixmapSelMargin = 0;
pixmapSelPattern = 0;
+ pixmapSelPatternOffset1 = 0;
pixmapIndentGuide = 0;
pixmapIndentGuideHighlight = 0;
@@ -217,6 +220,10 @@ Editor::Editor() {
convertPastes = true;
+ marginNumberPadding = 3;
+ ctrlCharPadding = 3; // +3 For a blank on front and rounded edge each side
+ lastSegItalicsOffset = 2;
+
hsStart = -1;
hsEnd = -1;
@@ -244,6 +251,8 @@ void Editor::DropGraphics(bool freeObjects) {
pixmapSelMargin = 0;
delete pixmapSelPattern;
pixmapSelPattern = 0;
+ delete pixmapSelPatternOffset1;
+ pixmapSelPatternOffset1 = 0;
delete pixmapIndentGuide;
pixmapIndentGuide = 0;
delete pixmapIndentGuideHighlight;
@@ -255,6 +264,8 @@ void Editor::DropGraphics(bool freeObjects) {
pixmapSelMargin->Release();
if (pixmapSelPattern)
pixmapSelPattern->Release();
+ if (pixmapSelPatternOffset1)
+ pixmapSelPatternOffset1->Release();
if (pixmapIndentGuide)
pixmapIndentGuide->Release();
if (pixmapIndentGuideHighlight)
@@ -269,6 +280,8 @@ void Editor::AllocateGraphics() {
pixmapSelMargin = Surface::Allocate(technology);
if (!pixmapSelPattern)
pixmapSelPattern = Surface::Allocate(technology);
+ if (!pixmapSelPatternOffset1)
+ pixmapSelPatternOffset1 = Surface::Allocate(technology);
if (!pixmapIndentGuide)
pixmapIndentGuide = Surface::Allocate(technology);
if (!pixmapIndentGuideHighlight)
@@ -302,13 +315,37 @@ void Editor::RefreshStyleData() {
}
}
+Point Editor::GetVisibleOriginInMain() {
+ return Point(0,0);
+}
+
+Point Editor::DocumentPointFromView(Point ptView) {
+ Point ptDocument = ptView;
+ if (wMargin.GetID()) {
+ Point ptOrigin = GetVisibleOriginInMain();
+ ptDocument.x += ptOrigin.x;
+ ptDocument.y += ptOrigin.y;
+ } else {
+ ptDocument.x += xOffset;
+ ptDocument.y += topLine * vs.lineHeight;
+ }
+ return ptDocument;
+}
+
+int Editor::TopLineOfMain() {
+ if (wMargin.GetID())
+ return 0;
+ else
+ return topLine;
+}
+
PRectangle Editor::GetClientRectangle() {
return wMain.GetClientPosition();
}
PRectangle Editor::GetTextRectangle() {
PRectangle rc = GetClientRectangle();
- rc.left += vs.fixedColumnWidth;
+ rc.left += vs.textStart;
rc.right -= vs.rightMarginWidth;
return rc;
}
@@ -431,7 +468,7 @@ Point Editor::LocationFromPosition(SelectionPosition pos) {
pt.y += vs.lineHeight;
}
}
- pt.x += vs.fixedColumnWidth - xOffset;
+ pt.x += vs.textStart - xOffset;
}
pt.x += pos.VirtualSpace() * vs.styles[ll->EndLineStyle()].spaceWidth;
return pt;
@@ -443,12 +480,12 @@ Point Editor::LocationFromPosition(int pos) {
int Editor::XFromPosition(int pos) {
Point pt = LocationFromPosition(pos);
- return pt.x - vs.fixedColumnWidth + xOffset;
+ return pt.x - vs.textStart + xOffset;
}
int Editor::XFromPosition(SelectionPosition sp) {
Point pt = LocationFromPosition(sp);
- return pt.x - vs.fixedColumnWidth + xOffset;
+ return pt.x - vs.textStart + xOffset;
}
int Editor::LineFromLocation(Point pt) {
@@ -456,7 +493,7 @@ int Editor::LineFromLocation(Point pt) {
}
void Editor::SetTopLine(int topLineNew) {
- if (topLine != topLineNew) {
+ if ((topLine != topLineNew) && (topLineNew >= 0)) {
topLine = topLineNew;
ContainerNeedsUpdate(SC_UPDATE_V_SCROLL);
}
@@ -469,16 +506,14 @@ SelectionPosition Editor::SPositionFromLocation(Point pt, bool canReturnInvalid,
PRectangle rcClient = GetTextRectangle();
if (!rcClient.Contains(pt))
return SelectionPosition(INVALID_POSITION);
- if (pt.x < vs.fixedColumnWidth)
+ if (pt.x < vs.textStart)
return SelectionPosition(INVALID_POSITION);
if (pt.y < 0)
return SelectionPosition(INVALID_POSITION);
}
- pt.x = pt.x - vs.fixedColumnWidth + xOffset;
- int visibleLine = pt.y / vs.lineHeight + topLine;
- if (pt.y < 0) { // Division rounds towards 0
- visibleLine = (static_cast<int>(pt.y) - (vs.lineHeight - 1)) / vs.lineHeight + topLine;
- }
+ pt = DocumentPointFromView(pt);
+ pt.x = pt.x - vs.textStart;
+ int visibleLine = floor(pt.y / vs.lineHeight);
if (!canReturnInvalid && (visibleLine < 0))
visibleLine = 0;
int lineDoc = cs.DocFromDisplay(visibleLine);
@@ -617,6 +652,8 @@ void Editor::Redraw() {
//Platform::DebugPrintf("Redraw all\n");
PRectangle rcClient = GetClientRectangle();
wMain.InvalidateRectangle(rcClient);
+ if (wMargin.GetID())
+ wMargin.InvalidateAll();
//wMain.InvalidateAll();
}
@@ -626,7 +663,7 @@ void Editor::RedrawSelMargin(int line, bool allAfter) {
Redraw();
} else {
PRectangle rcSelMargin = GetClientRectangle();
- rcSelMargin.right = vs.fixedColumnWidth;
+ rcSelMargin.right = rcSelMargin.left + vs.fixedColumnWidth;
if (line != -1) {
int position = pdoc->LineStart(line);
PRectangle rcLine = RectangleFromRange(position, position);
@@ -646,7 +683,13 @@ void Editor::RedrawSelMargin(int line, bool allAfter) {
if (!allAfter)
rcSelMargin.bottom = rcLine.bottom;
}
- wMain.InvalidateRectangle(rcSelMargin);
+ if (wMargin.GetID()) {
+ Point ptOrigin = GetVisibleOriginInMain();
+ rcSelMargin.Move(-ptOrigin.x, -ptOrigin.y);
+ wMargin.InvalidateRectangle(rcSelMargin);
+ } else {
+ wMain.InvalidateRectangle(rcSelMargin);
+ }
}
}
}
@@ -663,15 +706,13 @@ PRectangle Editor::RectangleFromRange(int start, int end) {
int maxLine = cs.DisplayFromDoc(lineDocMax) + cs.GetHeight(lineDocMax) - 1;
PRectangle rcClient = GetTextRectangle();
PRectangle rc;
- rc.left = vs.fixedColumnWidth;
- rc.top = (minLine - topLine) * vs.lineHeight;
- if (rc.top < 0)
- rc.top = 0;
+ const int leftTextOverlap = ((xOffset == 0) && (vs.leftMarginWidth > 0)) ? 1 : 0;
+ rc.left = vs.textStart - leftTextOverlap;
+ rc.top = (minLine - TopLineOfMain()) * vs.lineHeight;
+ if (rc.top < rcClient.top)
+ rc.top = rcClient.top;
rc.right = rcClient.right;
- rc.bottom = (maxLine - topLine + 1) * vs.lineHeight;
- // Ensure PRectangle is within 16 bit space
- rc.top = Platform::Clamp(rc.top, -32000, 32000);
- rc.bottom = Platform::Clamp(rc.bottom, -32000, 32000);
+ rc.bottom = (maxLine - TopLineOfMain() + 1) * vs.lineHeight;
return rc;
}
@@ -776,6 +817,7 @@ void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition ancho
if (highlightDelimiter.NeedsDrawing(currentLine)) {
RedrawSelMargin();
}
+ QueueIdleWork(WorkNeeded::workUpdateUI);
}
void Editor::SetSelection(int currentPos_, int anchor_) {
@@ -802,6 +844,7 @@ void Editor::SetSelection(SelectionPosition currentPos_) {
if (highlightDelimiter.NeedsDrawing(currentLine)) {
RedrawSelMargin();
}
+ QueueIdleWork(WorkNeeded::workUpdateUI);
}
void Editor::SetSelection(int currentPos_) {
@@ -822,6 +865,7 @@ void Editor::SetEmptySelection(SelectionPosition currentPos_) {
if (highlightDelimiter.NeedsDrawing(currentLine)) {
RedrawSelMargin();
}
+ QueueIdleWork(WorkNeeded::workUpdateUI);
}
void Editor::SetEmptySelection(int currentPos_) {
@@ -918,7 +962,8 @@ int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, b
// In case in need of wrapping to ensure DisplayFromDoc works.
if (currentLine >= wrapStart)
WrapLines(true, -1);
- XYScrollPosition newXY = XYScrollToMakeVisible(true, true, true);
+ XYScrollPosition newXY = XYScrollToMakeVisible(
+ SelectionRange(posDrag.IsValid() ? posDrag : sel.RangeMain().caret), xysDefault);
if (simpleCaret && (newXY.xOffset == xOffset)) {
// simple vertical scroll then invalidate
ScrollTo(newXY.topLine);
@@ -1189,17 +1234,20 @@ slop | strict | jumps | even | Caret can go to the margin | When
1 | 1 | 1 | 1 | No, kept out of UZ | moved to put caret at 3UZ of the
margin
*/
-Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const bool useMargin, const bool vert, const bool
horiz) {
+Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const SelectionRange range, const XYScrollOptions
options) {
PRectangle rcClient = GetTextRectangle();
- const SelectionPosition posCaret = posDrag.IsValid() ? posDrag : sel.RangeMain().caret;
- const Point pt = LocationFromPosition(posCaret);
+ Point pt = LocationFromPosition(range.caret);
+ Point ptAnchor = LocationFromPosition(range.anchor);
+ const Point ptOrigin = GetVisibleOriginInMain();
+ pt.x += ptOrigin.x;
+ ptAnchor.x += ptOrigin.x;
const Point ptBottomCaret(pt.x, pt.y + vs.lineHeight - 1);
- const int lineCaret = DisplayFromPosition(posCaret.Position());
XYScrollPosition newXY(xOffset, topLine);
// Vertical positioning
- if (vert && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || (caretYPolicy &
CARET_STRICT) != 0)) {
+ if ((options & xysVertical) && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom ||
(caretYPolicy & CARET_STRICT) != 0)) {
+ const int lineCaret = DisplayFromPosition(range.caret.Position());
const int linesOnScreen = LinesOnScreen();
const int halfScreen = Platform::Maximum(linesOnScreen - 1, 2) / 2;
const bool bSlop = (caretYPolicy & CARET_SLOP) != 0;
@@ -1213,7 +1261,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const bool useMargin, con
int yMoveT, yMoveB;
if (bStrict) {
int yMarginT, yMarginB;
- if (!useMargin) {
+ if (!(options & xysUseMargin)) {
// In drag mode, avoid moves
// otherwise, a double click will select several lines.
yMarginT = yMarginB = 0;
@@ -1283,11 +1331,23 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const bool useMargin, con
}
}
}
+ if (!(range.caret == range.anchor)) {
+ const int lineAnchor = DisplayFromPosition(range.anchor.Position());
+ if (lineAnchor < lineCaret) {
+ // Shift up to show anchor or as much of range as possible
+ newXY.topLine = std::min(newXY.topLine, lineAnchor);
+ newXY.topLine = std::max(newXY.topLine, lineCaret - LinesOnScreen());
+ } else {
+ // Shift down to show anchor or as much of range as possible
+ newXY.topLine = std::max(newXY.topLine, lineAnchor - LinesOnScreen());
+ newXY.topLine = std::min(newXY.topLine, lineCaret);
+ }
+ }
newXY.topLine = Platform::Clamp(newXY.topLine, 0, MaxScrollPos());
}
// Horizontal positioning
- if (horiz && (wrapState == eWrapNone)) {
+ if ((options & xysHorizontal) && (wrapState == eWrapNone)) {
const int halfScreen = Platform::Maximum(rcClient.Width() - 4, 4) / 2;
const bool bSlop = (caretXPolicy & CARET_SLOP) != 0;
const bool bStrict = (caretXPolicy & CARET_STRICT) != 0;
@@ -1298,7 +1358,7 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const bool useMargin, con
int xMoveL, xMoveR;
if (bStrict) {
int xMarginL, xMarginR;
- if (!useMargin) {
+ if (!(options & xysUseMargin)) {
// In drag mode, avoid moves unless very near of the margin
// otherwise, a simple click will select text.
xMarginL = xMarginR = 2;
@@ -1387,6 +1447,21 @@ Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const bool useMargin, con
newXY.xOffset += static_cast<int>(vs.aveCharWidth);
}
}
+ if (!(range.caret == range.anchor)) {
+ if (ptAnchor.x < pt.x) {
+ // Shift to left to show anchor or as much of range as possible
+ int maxOffset = ptAnchor.x + xOffset - rcClient.left - 1;
+ int minOffset = pt.x + xOffset - rcClient.right + 1;
+ newXY.xOffset = std::min(newXY.xOffset, maxOffset);
+ newXY.xOffset = std::max(newXY.xOffset, minOffset);
+ } else {
+ // Shift to right to show anchor or as much of range as possible
+ int minOffset = ptAnchor.x + xOffset - rcClient.right + 1;
+ int maxOffset = pt.x + xOffset - rcClient.left - 1;
+ newXY.xOffset = std::max(newXY.xOffset, minOffset);
+ newXY.xOffset = std::min(newXY.xOffset, maxOffset);
+ }
+ }
if (newXY.xOffset < 0) {
newXY.xOffset = 0;
}
@@ -1419,8 +1494,13 @@ void Editor::SetXYScroll(XYScrollPosition newXY) {
}
}
+void Editor::ScrollRange(SelectionRange range) {
+ SetXYScroll(XYScrollToMakeVisible(range, xysDefault));
+}
+
void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
- SetXYScroll(XYScrollToMakeVisible(useMargin, vert, horiz));
+ SetXYScroll(XYScrollToMakeVisible(SelectionRange(posDrag.IsValid() ? posDrag : sel.RangeMain().caret),
+
static_cast<XYScrollOptions>((useMargin?xysUseMargin:0)|(vert?xysVertical:0)|(horiz?xysHorizontal:0))));
}
void Editor::ShowCaretAtCurrentPosition() {
@@ -1536,8 +1616,8 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
int lineDocTop = cs.DocFromDisplay(topLine);
int subLineTop = topLine - cs.DisplayFromDoc(lineDocTop);
PRectangle rcTextArea = GetClientRectangle();
- rcTextArea.left = vs.fixedColumnWidth;
- rcTextArea.right -= vs.rightMarginWidth;
+ rcTextArea.left = vs.textStart;
+ rcTextArea.right -= vs.textStart;
wrapWidth = rcTextArea.Width();
RefreshStyleData();
AutoSurface surface(this);
@@ -1600,7 +1680,7 @@ void Editor::LinesJoin() {
UndoGroup ug(pdoc);
bool prevNonWS = true;
for (int pos = targetStart; pos < targetEnd; pos++) {
- if (IsEOLChar(pdoc->CharAt(pos))) {
+ if (pdoc->IsPositionInLineEnd(pos)) {
targetEnd -= pdoc->LenChar(pos);
pdoc->DelChar(pos);
if (prevNonWS) {
@@ -1747,7 +1827,12 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
if (vs.fixedColumnWidth == 0)
return;
+ RefreshPixMaps(surfWindow);
+
PRectangle rcMargin = GetClientRectangle();
+ Point ptOrigin = GetVisibleOriginInMain();
+ rcMargin.Move(0, -ptOrigin.y);
+ rcMargin.left = 0;
rcMargin.right = vs.fixedColumnWidth;
if (!rc.Intersects(rcMargin))
@@ -1768,18 +1853,24 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
PRectangle rcSelMargin = rcMargin;
rcSelMargin.right = rcMargin.left;
+ if (rcSelMargin.bottom < rc.bottom)
+ rcSelMargin.bottom = rc.bottom;
- for (int margin = 0; margin < vs.margins; margin++) {
+ for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) {
if (vs.ms[margin].width > 0) {
rcSelMargin.left = rcSelMargin.right;
rcSelMargin.right = rcSelMargin.left + vs.ms[margin].width;
if (vs.ms[margin].style != SC_MARGIN_NUMBER) {
- if (vs.ms[margin].mask & SC_MASK_FOLDERS)
+ if (vs.ms[margin].mask & SC_MASK_FOLDERS) {
// Required because of special way brush is created for selection
margin
- surface->FillRectangle(rcSelMargin, *pixmapSelPattern);
- else {
+ // Ensure patterns line up when scrolling with separate margin view
+ // by choosing correctly aligned variant.
+ bool invertPhase = static_cast<int>(ptOrigin.y) & 1;
+ surface->FillRectangle(rcSelMargin,
+ invertPhase ? *pixmapSelPattern : *pixmapSelPatternOffset1);
+ } else {
ColourDesired colour;
switch (vs.ms[margin].style) {
case SC_MARGIN_BACK:
@@ -1798,9 +1889,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
surface->FillRectangle(rcSelMargin, vs.styles[STYLE_LINENUMBER].back);
}
- const int lineStartPaint = rcMargin.top / vs.lineHeight;
- int visibleLine = topLine + lineStartPaint;
- int yposScreen = lineStartPaint * vs.lineHeight;
+ const int lineStartPaint = (rcMargin.top + ptOrigin.y) / vs.lineHeight;
+ int visibleLine = TopLineOfMain() + lineStartPaint;
+ int yposScreen = lineStartPaint * vs.lineHeight - ptOrigin.y;
// Work out whether the top line is whitespace located after a
// lessening of fold level which implies a 'fold tail' but which should not
// be displayed until the last of a sequence of whitespace.
@@ -1831,7 +1922,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
int folderEnd = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEREND,
SC_MARKNUM_FOLDER);
- while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) {
+ while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rc.bottom) {
PLATFORM_ASSERT(visibleLine < cs.LinesDisplayed());
int lineDoc = cs.DocFromDisplay(visibleLine);
@@ -1941,8 +2032,9 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
rcMarker.bottom = yposScreen + vs.lineHeight;
if (vs.ms[margin].style == SC_MARGIN_NUMBER) {
if (firstSubLine) {
- char number[100];
- sprintf(number, "%d", lineDoc + 1);
+ char number[100] = "";
+ if (lineDoc >= 0)
+ sprintf(number, "%d", lineDoc + 1);
if (foldFlags & SC_FOLDFLAG_LEVELNUMBERS) {
int lev = pdoc->GetLevel(lineDoc);
sprintf(number, "%c%c %03X %03X",
@@ -1955,7 +2047,7 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
PRectangle rcNumber = rcMarker;
// Right justify
XYPOSITION width =
surface->WidthText(vs.styles[STYLE_LINENUMBER].font, number, istrlen(number));
- XYPOSITION xpos = rcNumber.right - width - 3;
+ XYPOSITION xpos = rcNumber.right - width -
marginNumberPadding;
rcNumber.left = xpos;
surface->DrawTextNoClip(rcNumber,
vs.styles[STYLE_LINENUMBER].font,
rcNumber.top + vs.maxAscent, number,
istrlen(number),
@@ -2187,7 +2279,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
bool isBadUTF = isBadUTFNext;
isBadUTFNext = IsUnicodeMode() && BadUTF(ll->chars + charInLine + 1, numCharsInLine -
charInLine - 1, trailBytes);
if ((ll->styles[charInLine] != ll->styles[charInLine + 1]) ||
- isControl || isControlNext || isBadUTF || isBadUTFNext) {
+ isControl || isControlNext || isBadUTF || isBadUTFNext || ((charInLine+1) >=
numCharsBeforeEOL)) {
ll->positions[startseg] = 0;
if (vstyle.styles[ll->styles[charInLine]].visible) {
if (isControl) {
@@ -2197,9 +2289,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
} else if (controlCharSymbol < 32) {
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;
+ surface->WidthText(ctrlCharsFont,
ctrlChar, istrlen(ctrlChar)) + ctrlCharPadding;
}
ll->positions[charInLine + 1] =
ctrlCharWidth[ll->chars[charInLine]];
} else {
@@ -2208,7 +2299,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
ll->positions + startseg + 1);
}
lastSegItalics = false;
- } else if (isBadUTF) {
+ } else if ((isBadUTF) || (charInLine >= numCharsBeforeEOL)) {
char hexits[4];
sprintf(hexits, "x%2X", ll->chars[charInLine] & 0xff);
ll->positions[charInLine + 1] =
@@ -2239,7 +2330,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
}
// Small hack to make lines that end with italics not cut off the edge of the last character
if ((startseg > 0) && lastSegItalics) {
- ll->positions[startseg] += 2;
+ ll->positions[startseg] += lastSegItalicsOffset;
}
ll->numCharsInLine = numCharsInLine;
ll->numCharsBeforeEOL = numCharsBeforeEOL;
@@ -2499,7 +2590,15 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
rcSegment.left = xStart + ll->positions[eolPos] - subLineStart + virtualSpace;
rcSegment.right = xStart + ll->positions[eolPos+1] - subLineStart + virtualSpace;
blobsWidth += rcSegment.Width();
- const char *ctrlChar = ControlCharacterString(ll->chars[eolPos]);
+ char hexits[4];
+ const char *ctrlChar;
+ unsigned char chEOL = ll->chars[eolPos];
+ if (UTF8IsAscii(chEOL)) {
+ ctrlChar = ControlCharacterString(chEOL);
+ } else {
+ sprintf(hexits, "x%2X", chEOL);
+ ctrlChar = hexits;
+ }
int styleMain = ll->styles[eolPos];
ColourDesired textBack = TextBackground(vsDraw, overrideBackground, background,
eolInSelection, false, styleMain, eolPos, ll);
ColourDesired textFore = vsDraw.styles[styleMain].fore;
@@ -2738,7 +2837,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
// the color for the highest numbered one is used.
bool overrideBackground = false;
ColourDesired background;
- if (caret.active && vsDraw.showCaretLineBackground && (vsDraw.caretLineAlpha == SC_ALPHA_NOALPHA) &&
ll->containsCaret) {
+ if ((caret.active || vsDraw.alwaysShowCaretLineBackground) && vsDraw.showCaretLineBackground &&
(vsDraw.caretLineAlpha == SC_ALPHA_NOALPHA) && ll->containsCaret) {
overrideBackground = true;
background = vsDraw.caretLineBackground;
}
@@ -2984,12 +3083,6 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
textBack = vsDraw.whitespaceBackground;
surface->FillRectangle(rcSegment, textBack);
}
- if ((vsDraw.viewWhitespace != wsInvisible) ||
- (inIndentation && vsDraw.viewIndentationGuides != ivNone)) {
- if (vsDraw.whitespaceForegroundSet)
- textFore = vsDraw.whitespaceForeground;
- surface->PenColour(textFore);
- }
if (inIndentation && vsDraw.viewIndentationGuides == ivReal) {
for (int indentCount = (ll->positions[i] + epsilon) / indentWidth;
indentCount <= (ll->positions[i + 1] - epsilon) / indentWidth;
@@ -3003,6 +3096,9 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
}
if (vsDraw.viewWhitespace != wsInvisible) {
if (!inIndentation || vsDraw.viewWhitespace == wsVisibleAlways) {
+ if (vsDraw.whitespaceForegroundSet)
+ textFore = vsDraw.whitespaceForeground;
+ surface->PenColour(textFore);
PRectangle rcTab(rcSegment.left + 1, rcSegment.top + 4,
rcSegment.right - 1, rcSegment.bottom -
vsDraw.maxDescent);
DrawTabArrow(surface, rcTab, rcSegment.top +
vsDraw.lineHeight / 2);
@@ -3188,7 +3284,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
// Draw any translucent whole line states
rcSegment = rcLine;
- if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
+ if ((caret.active || vsDraw.alwaysShowCaretLineBackground) && vsDraw.showCaretLineBackground &&
ll->containsCaret) {
SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground, vsDraw.caretLineAlpha);
}
marks = pdoc->GetMark(line);
@@ -3228,7 +3324,7 @@ void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll,
// glyph / combining character. If so we'll need to draw that too.
int offsetFirstChar = offset;
int offsetLastChar = offset + (posAfter - posCaret);
- while ((offsetLastChar - numCharsToDraw) >= lineStart) {
+ while ((posBefore > 0) && ((offsetLastChar - numCharsToDraw) >= lineStart)) {
if ((ll->positions[offsetLastChar] - ll->positions[offsetLastChar - numCharsToDraw]) > 0) {
// The char does not share horizontal space
break;
@@ -3242,6 +3338,8 @@ void Editor::DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll,
// See if the next character shares horizontal space, if so we'll
// need to draw that too.
+ if (offsetFirstChar < 0)
+ offsetFirstChar = 0;
numCharsToDraw = offsetLastChar - offsetFirstChar;
while ((offsetLastChar < ll->LineStart(subLine + 1)) && (offsetLastChar <= ll->numCharsInLine)) {
// Update posAfter to point to the 2nd next char, this is where
@@ -3282,6 +3380,7 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
if (!pixmapSelPattern->Initialised()) {
const int patternSize = 8;
pixmapSelPattern->InitPixMap(patternSize, patternSize, surfaceWindow, wMain.GetID());
+ pixmapSelPatternOffset1->InitPixMap(patternSize, patternSize, surfaceWindow, wMain.GetID());
// This complex procedure is to reproduce the checkerboard dithered pattern used by windows
// for scroll bars and Visual Studio for its selection margin. The colour of this pattern is
half
// way between the chrome colour and the chrome highlight colour making a nice transition
@@ -3308,10 +3407,12 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
}
pixmapSelPattern->FillRectangle(rcPattern, colourFMFill);
+ pixmapSelPatternOffset1->FillRectangle(rcPattern, colourFMStripes);
for (int y = 0; y < patternSize; y++) {
for (int x = y % 2; x < patternSize; x+=2) {
PRectangle rcPixel(x, y, x+1, y+1);
pixmapSelPattern->FillRectangle(rcPixel, colourFMStripes);
+ pixmapSelPatternOffset1->FillRectangle(rcPixel, colourFMFill);
}
}
}
@@ -3432,27 +3533,27 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
AllocateGraphics();
RefreshStyleData();
+ if (paintState == paintAbandoned)
+ return; // Scroll bars may have changed so need redraw
RefreshPixMaps(surfaceWindow);
StyleToPositionInView(PositionAfterArea(rcArea));
PRectangle rcClient = GetClientRectangle();
+ Point ptOrigin = GetVisibleOriginInMain();
//Platform::DebugPrintf("Client: (%3d,%3d) ... (%3d,%3d) %d\n",
// rcClient.left, rcClient.top, rcClient.right, rcClient.bottom);
int screenLinePaintFirst = rcArea.top / vs.lineHeight;
- int xStart = vs.fixedColumnWidth - xOffset;
+ int xStart = vs.textStart - xOffset + ptOrigin.x;
int ypos = 0;
if (!bufferedDraw)
ypos += screenLinePaintFirst * vs.lineHeight;
int yposScreen = screenLinePaintFirst * vs.lineHeight;
bool paintAbandonedByStyling = paintState == paintAbandoned;
- if (needUpdateUI) {
- NotifyUpdateUI();
- needUpdateUI = 0;
-
+ if (NotifyUpdateUI()) {
RefreshStyleData();
RefreshPixMaps(surfaceWindow);
}
@@ -3477,12 +3578,20 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
surfaceWindow->SetClip(rcArea);
if (paintState != paintAbandoned) {
- PaintSelMargin(surfaceWindow, rcArea);
-
- PRectangle rcRightMargin = rcClient;
- rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth;
- if (rcArea.Intersects(rcRightMargin)) {
- surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back);
+ if (vs.marginInside) {
+ PaintSelMargin(surfaceWindow, rcArea);
+ PRectangle rcRightMargin = rcClient;
+ rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth;
+ if (rcArea.Intersects(rcRightMargin)) {
+ surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back);
+ }
+ } else { // Else separate view so separate paint event but leftMargin included to allow
overlap
+ PRectangle rcLeftMargin = rcArea;
+ rcLeftMargin.left = 0;
+ rcLeftMargin.right = rcLeftMargin.left + vs.leftMarginWidth;
+ if (rcArea.Intersects(rcLeftMargin)) {
+ surfaceWindow->FillRectangle(rcLeftMargin, vs.styles[STYLE_DEFAULT].back);
+ }
}
}
@@ -3501,8 +3610,12 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
}
//Platform::DebugPrintf("start display %d, offset = %d\n", pdoc->Length(), xOffset);
+ // Allow text at start of line to overlap 1 pixel into the margin as this displays
+ // serifs and italic stems for aliased text.
+ const int leftTextOverlap = ((xOffset == 0) && (vs.leftMarginWidth > 0)) ? 1 : 0;
+
// Do the painting
- if (rcArea.right > vs.fixedColumnWidth) {
+ if (rcArea.right > vs.textStart - leftTextOverlap) {
Surface *surface = surfaceWindow;
if (bufferedDraw) {
@@ -3512,7 +3625,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
surface->SetUnicodeMode(IsUnicodeMode());
surface->SetDBCSMode(CodePage());
- int visibleLine = topLine + screenLinePaintFirst;
+ int visibleLine = TopLineOfMain() + screenLinePaintFirst;
SelectionPosition posCaret = sel.RangeMain().caret;
if (posDrag.IsValid())
@@ -3520,13 +3633,19 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
int lineCaret = pdoc->LineFromPosition(posCaret.Position());
PRectangle rcTextArea = rcClient;
- rcTextArea.left = vs.fixedColumnWidth;
- rcTextArea.right -= vs.rightMarginWidth;
+ if (vs.marginInside) {
+ rcTextArea.left += vs.textStart;
+ rcTextArea.right -= vs.rightMarginWidth;
+ } else {
+ rcTextArea = rcArea;
+ }
// Remove selection margin from drawing area so text will not be drawn
// on it in unbuffered mode.
- if (!bufferedDraw) {
- surfaceWindow->SetClip(rcTextArea);
+ if (!bufferedDraw && vs.marginInside) {
+ PRectangle rcClipText = rcTextArea;
+ rcClipText.left -= leftTextOverlap;
+ surfaceWindow->SetClip(rcClipText);
}
// Loop on visible lines
@@ -3577,6 +3696,13 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
highlightGuideColumn * vs.spaceWidth, bracesIgnoreStyle);
+ if (leftTextOverlap && bufferedDraw) {
+ PRectangle rcSpacer = rcLine;
+ rcSpacer.right = rcSpacer.left;
+ rcSpacer.left -= 1;
+ surface->FillRectangle(rcSpacer, vs.styles[STYLE_DEFAULT].back);
+ }
+
// Draw the line
DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
//durPaint += et.Duration(true);
@@ -3610,8 +3736,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
DrawCarets(surface, vs, lineDoc, xStart, rcLine, ll, subLine);
if (bufferedDraw) {
- Point from(vs.fixedColumnWidth, 0);
- PRectangle rcCopyArea(vs.fixedColumnWidth, yposScreen,
+ Point from(vs.textStart-leftTextOverlap, 0);
+ PRectangle rcCopyArea(vs.textStart-leftTextOverlap, yposScreen,
rcClient.right - vs.rightMarginWidth, yposScreen +
vs.lineHeight);
surfaceWindow->Copy(rcCopyArea, from, *pixmapLine);
}
@@ -3635,10 +3761,10 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
// durPaint = 0.00000001;
// Right column limit indicator
- PRectangle rcBeyondEOF = rcClient;
- rcBeyondEOF.left = vs.fixedColumnWidth;
- rcBeyondEOF.right = rcBeyondEOF.right - vs.rightMarginWidth;
- rcBeyondEOF.top = (cs.LinesDisplayed() - topLine) * vs.lineHeight;
+ PRectangle rcBeyondEOF = (vs.marginInside) ? rcClient : rcArea;
+ rcBeyondEOF.left = vs.textStart;
+ rcBeyondEOF.right = rcBeyondEOF.right - ((vs.marginInside) ? vs.rightMarginWidth : 0);
+ rcBeyondEOF.top = (cs.LinesDisplayed() - TopLineOfMain()) * vs.lineHeight;
if (rcBeyondEOF.top < rcBeyondEOF.bottom) {
surfaceWindow->FillRectangle(rcBeyondEOF, vs.styles[STYLE_DEFAULT].back);
if (vs.edgeState == EDGE_LINE) {
@@ -3696,7 +3822,7 @@ long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
// Modify the view style for printing as do not normally want any of the transient features to be
printed
// Printing supports only the line number margin.
int lineNumberIndex = -1;
- for (int margin = 0; margin < ViewStyle::margins; margin++) {
+ for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) {
if ((vsPrint.ms[margin].style == SC_MARGIN_NUMBER) && (vsPrint.ms[margin].width > 0)) {
lineNumberIndex = margin;
} else {
@@ -3716,6 +3842,7 @@ long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
vsPrint.whitespaceBackgroundSet = false;
vsPrint.whitespaceForegroundSet = false;
vsPrint.showCaretLineBackground = false;
+ vsPrint.alwaysShowCaretLineBackground = false;
// Don't highlight matching braces using indicators
vsPrint.braceHighlightIndicatorSet = false;
vsPrint.braceBadLightIndicatorSet = false;
@@ -3791,7 +3918,7 @@ long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
// Copy this line and its styles from the document into local arrays
// and determine the x position at which each character starts.
- LineLayout ll(8000);
+ LineLayout ll(pdoc->LineStart(lineDoc+1)-pdoc->LineStart(lineDoc)+1);
LayoutLine(lineDoc, surfaceMeasure, vsPrint, &ll, widthPrint);
ll.containsCaret = false;
@@ -3907,7 +4034,7 @@ void Editor::ChangeSize() {
SetScrollBars();
if (wrapState != eWrapNone) {
PRectangle rcTextArea = GetClientRectangle();
- rcTextArea.left = vs.fixedColumnWidth;
+ rcTextArea.left = vs.textStart;
rcTextArea.right -= vs.rightMarginWidth;
if (wrapWidth != rcTextArea.Width()) {
NeedWrapping();
@@ -3972,7 +4099,7 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
}
} else if (inOverstrike) {
if (positionInsert < pdoc->Length()) {
- if (!IsEOLChar(pdoc->CharAt(positionInsert))) {
+ if (!pdoc->IsPositionInLineEnd(positionInsert)) {
pdoc->DelChar(positionInsert);
currentSel->ClearVirtualSpace();
}
@@ -4217,7 +4344,7 @@ void Editor::Clear() {
else
sel.Range(r) =
SelectionPosition(InsertSpace(sel.Range(r).caret.Position(), sel.Range(r).caret.VirtualSpace()));
}
- if ((sel.Count() == 1) ||
!IsEOLChar(pdoc->CharAt(sel.Range(r).caret.Position()))) {
+ if ((sel.Count() == 1) ||
!pdoc->IsPositionInLineEnd(sel.Range(r).caret.Position())) {
pdoc->DelChar(sel.Range(r).caret.Position());
sel.Range(r).ClearVirtualSpace();
} // else multiple selection so don't eat line ends
@@ -4301,10 +4428,12 @@ void Editor::DelCharBack(bool allowLineStartDeletion) {
sel.Range(r).ClearVirtualSpace();
}
}
+ ThinRectangularRange();
} else {
ClearSelection();
}
sel.RemoveDuplicates();
+ ContainerNeedsUpdate(SC_UPDATE_SELECTION);
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
}
@@ -4393,11 +4522,16 @@ void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool
NotifyParent(scn);
}
-void Editor::NotifyUpdateUI() {
- SCNotification scn = {0};
- scn.nmhdr.code = SCN_UPDATEUI;
- scn.updated = needUpdateUI;
- NotifyParent(scn);
+bool Editor::NotifyUpdateUI() {
+ if (needUpdateUI) {
+ SCNotification scn = {0};
+ scn.nmhdr.code = SCN_UPDATEUI;
+ scn.updated = needUpdateUI;
+ NotifyParent(scn);
+ needUpdateUI = 0;
+ return true;
+ }
+ return false;
}
void Editor::NotifyPainted() {
@@ -4420,9 +4554,9 @@ void Editor::NotifyIndicatorClick(bool click, int position, bool shift, bool ctr
bool Editor::NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt) {
int marginClicked = -1;
- int x = 0;
- for (int margin = 0; margin < ViewStyle::margins; margin++) {
- if ((pt.x > x) && (pt.x < x + vs.ms[margin].width))
+ int x = vs.textStart - vs.fixedColumnWidth;
+ for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) {
+ if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width))
marginClicked = margin;
x += vs.ms[margin].width;
}
@@ -4605,18 +4739,13 @@ void Editor::NotifyModified(Document *, DocModification mh, void *) {
}
}
- //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 && !CanDeferToLastStep(mh)) {
- QueueStyling(pdoc->Length());
+ QueueIdleWork(WorkNeeded::workStyle, pdoc->Length());
Redraw();
}
} else {
- //Platform::DebugPrintf("** %x Line Changed %d .. %d\n", this,
- // mh.position, mh.position + mh.length);
if (paintState == notPainting && mh.length && !CanEliminate(mh)) {
- QueueStyling(mh.position + mh.length);
+ QueueIdleWork(WorkNeeded::workStyle, mh.position + mh.length);
InvalidateRange(mh.position, mh.position + mh.length);
}
}
@@ -4743,6 +4872,8 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
case SCI_VCHOMEEXTEND:
case SCI_VCHOMEWRAP:
case SCI_VCHOMEWRAPEXTEND:
+ case SCI_VCHOMEDISPLAY:
+ case SCI_VCHOMEDISPLAYEXTEND:
case SCI_DELWORDLEFT:
case SCI_DELWORDRIGHT:
case SCI_DELWORDRIGHTEND:
@@ -5142,6 +5273,8 @@ int Editor::KeyCommand(unsigned int iMessage) {
SelectionPosition spCaret = sel.RangeMain().caret;
spCaret.SetVirtualSpace(spCaret.VirtualSpace() - 1);
MovePositionTo(spCaret);
+ } else if (sel.MoveExtends() && sel.selType == Selection::selStream) {
+ MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() - 1),
-1));
} else {
MovePositionTo(MovePositionSoVisible(
SelectionPosition((sel.LimitsForRectangularElseMain().start).Position() - 1), -1));
@@ -5177,6 +5310,8 @@ int Editor::KeyCommand(unsigned int iMessage) {
SelectionPosition spCaret = sel.RangeMain().caret;
spCaret.SetVirtualSpace(spCaret.VirtualSpace() + 1);
MovePositionTo(spCaret);
+ } else if (sel.MoveExtends() && sel.selType == Selection::selStream) {
+ MovePositionTo(MovePositionSoVisible(SelectionPosition(sel.MainCaret() + 1),
1));
} else {
MovePositionTo(MovePositionSoVisible(
SelectionPosition((sel.LimitsForRectangularElseMain().end).Position()
+ 1), 1));
@@ -5537,11 +5672,31 @@ int Editor::KeyCommand(unsigned int iMessage) {
StartEndDisplayLine(sel.MainCaret(), true), -1));
SetLastXChosen();
break;
+ case SCI_VCHOMEDISPLAY: {
+ SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret()));
+ SelectionPosition viewLineStart =
MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+ if (viewLineStart > homePos)
+ homePos = viewLineStart;
+
+ MovePositionTo(homePos);
+ SetLastXChosen();
+ }
+ break;
case SCI_HOMEDISPLAYEXTEND:
MovePositionTo(MovePositionSoVisible(
StartEndDisplayLine(sel.MainCaret(), true), -1), Selection::selStream);
SetLastXChosen();
break;
+ case SCI_VCHOMEDISPLAYEXTEND: {
+ SelectionPosition homePos = SelectionPosition(pdoc->VCHomePosition(sel.MainCaret()));
+ SelectionPosition viewLineStart =
MovePositionSoVisible(StartEndDisplayLine(sel.MainCaret(), true), -1);
+ if (viewLineStart > homePos)
+ homePos = viewLineStart;
+
+ MovePositionTo(homePos, Selection::selStream);
+ SetLastXChosen();
+ }
+ break;
case SCI_LINEENDDISPLAY:
MovePositionTo(MovePositionSoVisible(
StartEndDisplayLine(sel.MainCaret(), false), 1));
@@ -5689,15 +5844,15 @@ long Editor::FindText(
Sci_TextToFind *ft = reinterpret_cast<Sci_TextToFind *>(lParam);
int lengthFound = istrlen(ft->lpstrText);
- std::auto_ptr<CaseFolder> pcf(CaseFolderForEncoding());
+ if (!pdoc->HasCaseFolder())
+ pdoc->SetCaseFolder(CaseFolderForEncoding());
int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText,
(wParam & SCFIND_MATCHCASE) != 0,
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound,
- pcf.get());
+ &lengthFound);
if (pos != -1) {
ft->chrgText.cpMin = pos;
ft->chrgText.cpMax = pos + lengthFound;
@@ -5720,19 +5875,6 @@ void Editor::SearchAnchor() {
searchAnchor = SelectionStart().Position();
}
-// Simple RAII wrapper for CaseFolder as std::auto_ptr is now deprecated
-class ScopedCaseFolder {
- CaseFolder *pcf;
-public:
- ScopedCaseFolder(CaseFolder *pcf_) : pcf(pcf_) {
- }
- ~ScopedCaseFolder() {
- delete pcf;
- pcf = 0;
- }
- CaseFolder *get() const { return pcf; }
-};
-
/**
* Find text from current search anchor: Must call @c SearchAnchor first.
* Used for next text and previous text requests.
@@ -5747,7 +5889,8 @@ long Editor::SearchText(
const char *txt = reinterpret_cast<char *>(lParam);
int pos;
int lengthFound = istrlen(txt);
- ScopedCaseFolder pcf(CaseFolderForEncoding());
+ if (!pdoc->HasCaseFolder())
+ pdoc->SetCaseFolder(CaseFolderForEncoding());
if (iMessage == SCI_SEARCHNEXT) {
pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt,
(wParam & SCFIND_MATCHCASE) != 0,
@@ -5755,8 +5898,7 @@ long Editor::SearchText(
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound,
- pcf.get());
+ &lengthFound);
} else {
pos = pdoc->FindText(searchAnchor, 0, txt,
(wParam & SCFIND_MATCHCASE) != 0,
@@ -5764,8 +5906,7 @@ long Editor::SearchText(
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound,
- pcf.get());
+ &lengthFound);
}
if (pos != -1) {
SetSelection(pos, pos + lengthFound);
@@ -5798,15 +5939,15 @@ std::string Editor::CaseMapString(const std::string &s, int caseMapping) {
long Editor::SearchInTarget(const char *text, int length) {
int lengthFound = length;
- ScopedCaseFolder pcf(CaseFolderForEncoding());
+ if (!pdoc->HasCaseFolder())
+ pdoc->SetCaseFolder(CaseFolderForEncoding());
int pos = pdoc->FindText(targetStart, targetEnd, text,
(searchFlags & SCFIND_MATCHCASE) != 0,
(searchFlags & SCFIND_WHOLEWORD) != 0,
(searchFlags & SCFIND_WORDSTART) != 0,
(searchFlags & SCFIND_REGEXP) != 0,
searchFlags,
- &lengthFound,
- pcf.get());
+ &lengthFound);
if (pos != -1) {
targetStart = pos;
targetEnd = pos + lengthFound;
@@ -5845,6 +5986,18 @@ char *Editor::CopyRange(int start, int end) {
return text;
}
+std::string Editor::RangeText(int start, int end) const {
+ if (start < end) {
+ int len = end - start;
+ std::string ret(len, '\0');
+ for (int i = 0; i < len; i++) {
+ ret[i] = pdoc->CharAt(start + i);
+ }
+ return ret;
+ }
+ return std::string();
+}
+
void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) {
if (sel.Empty()) {
if (allowLineCopy) {
@@ -5859,11 +6012,11 @@ void Editor::CopySelectionRange(SelectionText *ss, bool allowLineCopy) {
char *textWithEndl = new char[textLen];
textWithEndl[0] = '\0';
if (text)
- strncat(textWithEndl, text, textLen);
+ strcat(textWithEndl, text);
if (pdoc->eolMode != SC_EOL_LF)
- strncat(textWithEndl, "\r", textLen);
+ strcat(textWithEndl, "\r");
if (pdoc->eolMode != SC_EOL_CR)
- strncat(textWithEndl, "\n", textLen);
+ strcat(textWithEndl, "\n");
ss->Set(textWithEndl, static_cast<int>(strlen(textWithEndl) + 1),
pdoc->dbcsCodePage, vs.styles[STYLE_DEFAULT].characterSet, false, true);
delete []text;
@@ -6055,7 +6208,8 @@ bool Editor::PointInSelMargin(Point pt) {
// Really means: "Point in a margin"
if (vs.fixedColumnWidth > 0) { // There is a margin
PRectangle rcSelMargin = GetClientRectangle();
- rcSelMargin.right = vs.fixedColumnWidth - vs.leftMarginWidth;
+ rcSelMargin.right = vs.textStart - vs.leftMarginWidth;
+ rcSelMargin.left = vs.textStart - vs.fixedColumnWidth;
return rcSelMargin.Contains(pt);
} else {
return false;
@@ -6064,7 +6218,7 @@ bool Editor::PointInSelMargin(Point pt) {
Window::Cursor Editor::GetMarginCursor(Point pt) {
int x = 0;
- for (int margin = 0; margin < ViewStyle::margins; margin++) {
+ for (int margin = 0; margin <= SC_MAX_MARGIN; margin++) {
if ((pt.x >= x) && (pt.x < x + vs.ms[margin].width))
return static_cast<Window::Cursor>(vs.ms[margin].cursor);
x += vs.ms[margin].width;
@@ -6445,6 +6599,8 @@ void Editor::ButtonMove(Point pt) {
// Autoscroll
PRectangle rcClient = GetClientRectangle();
+ Point ptOrigin = GetVisibleOriginInMain();
+ rcClient.Move(0, -ptOrigin.y);
int lineMove = DisplayFromPosition(movePos.Position());
if (pt.y > rcClient.bottom) {
ScrollTo(lineMove - LinesOnScreen() + 1);
@@ -6644,7 +6800,7 @@ int Editor::PositionAfterArea(PRectangle rcArea) {
// Style to a position within the view. If this causes a change at end of last line then
// affects later lines so style all the viewed text.
void Editor::StyleToPositionInView(Position pos) {
- int endWindow = PositionAfterArea(GetClientRectangle());
+ int endWindow = (vs.marginInside) ? (PositionAfterArea(GetClientRectangle())) : (pdoc->Length());
if (pos > endWindow)
pos = endWindow;
int styleAtEnd = pdoc->StyleAt(pos-1);
@@ -6656,20 +6812,18 @@ void Editor::StyleToPositionInView(Position pos) {
}
}
-void Editor::IdleStyling() {
+void Editor::IdleWork() {
// Style the line after the modification as this allows modifications that change just the
// line of the modification to heal instead of propagating to the rest of the window.
- StyleToPositionInView(pdoc->LineStart(pdoc->LineFromPosition(styleNeeded.upTo) + 2));
+ if (workNeeded.items & WorkNeeded::workStyle)
+ StyleToPositionInView(pdoc->LineStart(pdoc->LineFromPosition(workNeeded.upTo) + 2));
- if (needUpdateUI) {
- NotifyUpdateUI();
- needUpdateUI = 0;
- }
- styleNeeded.Reset();
+ NotifyUpdateUI();
+ workNeeded.Reset();
}
-void Editor::QueueStyling(int upTo) {
- styleNeeded.NeedUpTo(upTo);
+void Editor::QueueIdleWork(WorkNeeded::workItems items, int upTo) {
+ workNeeded.Need(items, upTo);
}
bool Editor::PaintContains(PRectangle rc) {
@@ -6681,8 +6835,13 @@ bool Editor::PaintContains(PRectangle rc) {
}
bool Editor::PaintContainsMargin() {
+ if (wMargin.GetID()) {
+ // With separate margin view, paint of text view
+ // never contains margin.
+ return false;
+ }
PRectangle rcSelMargin = GetClientRectangle();
- rcSelMargin.right = vs.fixedColumnWidth;
+ rcSelMargin.right = vs.textStart;
return PaintContains(rcSelMargin);
}
@@ -6767,6 +6926,8 @@ void Editor::SetDocPointer(Document *document) {
braces[0] = invalidPosition;
braces[1] = invalidPosition;
+ vs.ReleaseAllExtendedStyles();
+
// Reset the contraction state to fully shown.
cs.Clear();
cs.InsertLines(0, pdoc->LinesTotal() - 1);
@@ -6878,12 +7039,17 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) {
WrapLines(true, -1);
if (!cs.GetVisible(lineDoc)) {
+ // Back up to find a non-blank line
int lookLine = lineDoc;
int lookLineLevel = pdoc->GetLevel(lookLine);
while ((lookLine > 0) && (lookLineLevel & SC_FOLDLEVELWHITEFLAG)) {
lookLineLevel = pdoc->GetLevel(--lookLine);
}
int lineParent = pdoc->GetFoldParent(lookLine);
+ if (lineParent < 0) {
+ // Backed up to a top level line, so try to find parent of initial line
+ lineParent = pdoc->GetFoldParent(lineDoc);
+ }
if (lineParent >= 0) {
if (lineDoc != lineParent)
EnsureLineVisible(lineParent, enforcePolicy);
@@ -6919,10 +7085,10 @@ void Editor::EnsureLineVisible(int lineDoc, bool enforcePolicy) {
}
int Editor::GetTag(char *tagValue, int tagNumber) {
- char name[3] = "\\?";
const char *text = 0;
int length = 0;
if ((tagNumber >= 1) && (tagNumber <= 9)) {
+ char name[3] = "\\?";
name[1] = static_cast<char>(tagNumber + '0');
length = 2;
text = pdoc->SubstituteByPosition(name, &length);
@@ -6996,7 +7162,7 @@ void Editor::AddStyledText(char *buffer, int appendLength) {
}
static bool ValidMargin(unsigned long wParam) {
- return wParam < ViewStyle::margins;
+ return wParam <= SC_MAX_MARGIN;
}
static char *CharPtrFromSPtr(sptr_t lParam) {
@@ -7043,6 +7209,7 @@ void Editor::StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam
break;
case SCI_STYLESETCHARACTERSET:
vs.styles[wParam].characterSet = lParam;
+ pdoc->SetCaseFolder(NULL);
break;
case SCI_STYLESETVISIBLE:
vs.styles[wParam].visible = lParam != 0;
@@ -7353,7 +7520,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_LINESCROLL:
ScrollTo(topLine + lParam);
- HorizontalScrollTo(xOffset + wParam * vs.spaceWidth);
+ HorizontalScrollTo(xOffset + static_cast<int>(wParam) * vs.spaceWidth);
return 1;
case SCI_SETXOFFSET:
@@ -7389,7 +7556,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return 0;
} else {
Point pt = LocationFromPosition(lParam);
- return pt.x;
+ // Convert to view-relative
+ return pt.x - vs.textStart + vs.fixedColumnWidth;
}
case SCI_POINTYFROMPOSITION:
@@ -7510,6 +7678,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
caret.period = wParam;
break;
+ case SCI_GETWORDCHARS:
+ return pdoc->GetCharsOfClass(CharClassify::ccWord, reinterpret_cast<unsigned char *>(lParam));
+
case SCI_SETWORDCHARS: {
pdoc->SetDefaultCharClasses(false);
if (lParam == 0)
@@ -7518,6 +7689,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
}
break;
+ case SCI_GETWHITESPACECHARS:
+ return pdoc->GetCharsOfClass(CharClassify::ccSpace, reinterpret_cast<unsigned char
*>(lParam));
+
case SCI_SETWHITESPACECHARS: {
if (lParam == 0)
return 0;
@@ -7525,6 +7699,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
}
break;
+ case SCI_GETPUNCTUATIONCHARS:
+ return pdoc->GetCharsOfClass(CharClassify::ccPunctuation, reinterpret_cast<unsigned char
*>(lParam));
+
+ case SCI_SETPUNCTUATIONCHARS: {
+ if (lParam == 0)
+ return 0;
+ pdoc->SetCharClasses(reinterpret_cast<unsigned char *>(lParam),
CharClassify::ccPunctuation);
+ }
+ break;
+
case SCI_SETCHARSDEFAULT:
pdoc->SetDefaultCharClasses(true);
break;
@@ -7710,6 +7894,21 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
pdoc->eolMode = wParam;
break;
+ case SCI_SETLINEENDTYPESALLOWED:
+ if (pdoc->SetLineEndTypesAllowed(wParam)) {
+ cs.Clear();
+ cs.InsertLines(0, pdoc->LinesTotal() - 1);
+ SetAnnotationHeights(0, pdoc->LinesTotal());
+ InvalidateStyleRedraw();
+ }
+ break;
+
+ case SCI_GETLINEENDTYPESALLOWED:
+ return pdoc->GetLineEndTypesAllowed();
+
+ case SCI_GETLINEENDTYPESACTIVE:
+ return pdoc->GetLineEndTypesActive();
+
case SCI_STARTSTYLING:
pdoc->StartStyling(wParam, static_cast<char>(lParam));
break;
@@ -7976,6 +8175,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
verticalScrollBarVisible = wParam != 0;
SetScrollBars();
ReconfigureScrollBars();
+ if (verticalScrollBarVisible)
+ SetVerticalScrollPos();
}
break;
@@ -8005,8 +8206,12 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETCODEPAGE:
if (ValidCodePage(wParam)) {
- pdoc->dbcsCodePage = wParam;
- InvalidateStyleRedraw();
+ if (pdoc->SetDBCSCodePage(wParam)) {
+ cs.Clear();
+ cs.InsertLines(0, pdoc->LinesTotal() - 1);
+ SetAnnotationHeights(0, pdoc->LinesTotal());
+ InvalidateStyleRedraw();
+ }
}
break;
@@ -8113,9 +8318,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
sizeRGBAImage.y = wParam;
break;
+ case SCI_RGBAIMAGESETSCALE:
+ scaleRGBAImage = wParam;
+ break;
+
case SCI_MARKERDEFINERGBAIMAGE:
if (wParam <= MARKER_MAX) {
- vs.markers[wParam].SetRGBAImage(sizeRGBAImage, reinterpret_cast<unsigned char
*>(lParam));
+ vs.markers[wParam].SetRGBAImage(sizeRGBAImage, scaleRGBAImage / 100.0,
reinterpret_cast<unsigned char *>(lParam));
vs.CalcLargestMarkerHeight();
};
InvalidateStyleData();
@@ -8255,6 +8464,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
vs.showCaretLineBackground = wParam != 0;
InvalidateStyleRedraw();
break;
+ case SCI_GETCARETLINEVISIBLEALWAYS:
+ return vs.alwaysShowCaretLineBackground;
+ case SCI_SETCARETLINEVISIBLEALWAYS:
+ vs.alwaysShowCaretLineBackground = wParam != 0;
+ InvalidateStyleRedraw();
+ break;
+
case SCI_GETCARETLINEBACK:
return vs.caretLineBackground.AsLong();
case SCI_SETCARETLINEBACK:
@@ -8343,6 +8559,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
EnsureLineVisible(wParam, true);
break;
+ case SCI_SCROLLRANGE:
+ ScrollRange(SelectionRange(lParam, wParam));
+ break;
+
case SCI_SEARCHANCHOR:
SearchAnchor();
break;
@@ -8595,6 +8815,8 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_VCHOMEEXTEND:
case SCI_VCHOMEWRAP:
case SCI_VCHOMEWRAPEXTEND:
+ case SCI_VCHOMEDISPLAY:
+ case SCI_VCHOMEDISPLAYEXTEND:
case SCI_ZOOMIN:
case SCI_ZOOMOUT:
case SCI_DELWORDLEFT:
@@ -9055,6 +9277,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_ANNOTATIONGETSTYLEOFFSET:
return vs.annotationStyleOffset;
+ case SCI_RELEASEALLEXTENDEDSTYLES:
+ vs.ReleaseAllExtendedStyles();
+ break;
+
+ case SCI_ALLOCATEEXTENDEDSTYLES:
+ return vs.AllocateExtendedStyles(wParam);
+
case SCI_ADDUNDOACTION:
pdoc->AddUndoAction(wParam, lParam & UNDO_MAY_COALESCE);
break;
@@ -9101,6 +9330,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_GETSELECTIONS:
return sel.Count();
+ case SCI_GETSELECTIONEMPTY:
+ return sel.Empty();
+
case SCI_CLEARSELECTIONS:
sel.Clear();
Redraw();
diff --git a/plugins/scintilla/scintilla/src/Editor.h b/plugins/scintilla/scintilla/src/Editor.h
index f8ab19d..f2b452a 100644
--- a/plugins/scintilla/scintilla/src/Editor.h
+++ b/plugins/scintilla/scintilla/src/Editor.h
@@ -47,21 +47,30 @@ public:
/**
* When platform has a way to generate an event before painting,
- * accumulate needed styling range in StyleNeeded to avoid unnecessary work.
+ * accumulate needed styling range and other work items in
+ * WorkNeeded to avoid unnecessary work inside paint handler
*/
-class StyleNeeded {
+class WorkNeeded {
public:
+ enum workItems {
+ workNone=0,
+ workStyle=1,
+ workUpdateUI=2
+ };
bool active;
+ enum workItems items;
Position upTo;
- StyleNeeded() : active(false), upTo(0) {}
+ WorkNeeded() : active(false), items(workNone), upTo(0) {}
void Reset() {
active = false;
+ items = workNone;
upTo = 0;
}
- void NeedUpTo(Position pos) {
- if (upTo < pos)
+ void Need(workItems items_, Position pos) {
+ if ((items_ & workStyle) && (upTo < pos))
upTo = pos;
+ items = static_cast<workItems>(items | items_);
}
};
@@ -95,6 +104,7 @@ public:
characterSet = characterSet_;
rectangular = rectangular_;
lineCopy = lineCopy_;
+ FixSelectionForClipboard();
}
void Copy(const char *s_, int len_, int codePage_, int characterSet_, bool rectangular_, bool
lineCopy_) {
delete []s;
@@ -108,10 +118,22 @@ public:
characterSet = characterSet_;
rectangular = rectangular_;
lineCopy = lineCopy_;
+ FixSelectionForClipboard();
}
void Copy(const SelectionText &other) {
Copy(other.s, other.len, other.codePage, other.characterSet, other.rectangular,
other.lineCopy);
}
+
+private:
+ void FixSelectionForClipboard() {
+ // Replace null characters by spaces.
+ // To avoid that the content of the clipboard is truncated in the paste operation
+ // when the clipboard contains null characters.
+ for (int i = 0; i < len - 1; ++i) {
+ if (s[i] == '\0')
+ s[i] = ' ';
+ }
+ }
};
/**
@@ -126,6 +148,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
/** On GTK+, Scintilla is a container widget holding two scroll bars
* whereas on Windows there is just one window with both scroll bars turned on. */
Window wMain; ///< The Scintilla parent window
+ Window wMargin; ///< May be separate when using a scroll view for wMain
/** Style resources may be expensive to allocate so are cached between uses.
* When a style attribute is changed, this cache is flushed. */
@@ -133,6 +156,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
ViewStyle vs;
int technology;
Point sizeRGBAImage;
+ float scaleRGBAImage;
int printMagnification;
int printColourMode;
@@ -176,6 +200,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
Surface *pixmapLine;
Surface *pixmapSelMargin;
Surface *pixmapSelPattern;
+ Surface *pixmapSelPatternOffset1;
Surface *pixmapIndentGuide;
Surface *pixmapIndentGuideHighlight;
@@ -227,7 +252,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
PRectangle rcPaint;
bool paintingAllText;
bool willRedrawAll;
- StyleNeeded styleNeeded;
+ WorkNeeded workNeeded;
int modEventMask;
@@ -268,6 +293,10 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool convertPastes;
+ int marginNumberPadding; // the right-side padding of the number margin
+ int ctrlCharPadding; // the padding around control character text blobs
+ int lastSegItalicsOffset; // the offset so as not to clip italic characters at EOLs
+
Document *pdoc;
Editor();
@@ -281,6 +310,11 @@ protected: // ScintillaBase subclass needs access to much of Editor
void DropGraphics(bool freeObjects);
void AllocateGraphics();
+ // The top left visible point in main window coordinates. Will be 0,0 except for
+ // scroll views where it will be equivalent to the current scroll position.
+ virtual Point GetVisibleOriginInMain();
+ Point DocumentPointFromView(Point ptView); // Convert a point from view space to document
+ int TopLineOfMain(); // Return the line at Main's y coordinate 0
virtual PRectangle GetClientRectangle();
PRectangle GetTextRectangle();
@@ -347,10 +381,19 @@ protected: // ScintillaBase subclass needs access to much of Editor
int xOffset;
int topLine;
XYScrollPosition(int xOffset_, int topLine_) : xOffset(xOffset_), topLine(topLine_) {}
+ bool operator==(const XYScrollPosition &other) const {
+ return (xOffset == other.xOffset) && (topLine == other.topLine);
+ }
};
- XYScrollPosition XYScrollToMakeVisible(const bool useMargin, const bool vert, const bool horiz);
+ enum XYScrollOptions {
+ xysUseMargin=0x1,
+ xysVertical=0x2,
+ xysHorizontal=0x4,
+ xysDefault=xysUseMargin|xysVertical|xysHorizontal};
+ XYScrollPosition XYScrollToMakeVisible(const SelectionRange range, const XYScrollOptions options);
void SetXYScroll(XYScrollPosition newXY);
void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true);
+ void ScrollRange(SelectionRange range);
void ShowCaretAtCurrentPosition();
void DropCaret();
void InvalidateCaret();
@@ -434,7 +477,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt);
void NotifyHotSpotDoubleClicked(int position, bool shift, bool ctrl, bool alt);
void NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt);
- void NotifyUpdateUI();
+ bool NotifyUpdateUI();
void NotifyPainted();
void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt);
bool NotifyMarginClick(Point pt, bool shift, bool ctrl, bool alt);
@@ -480,6 +523,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void CopyToClipboard(const SelectionText &selectedText) = 0;
char *CopyRange(int start, int end);
+ std::string RangeText(int start, int end) const;
void CopySelectionRange(SelectionText *ss, bool allowLineCopy=false);
void CopyRangeToClipboard(int start, int end);
void CopyText(int length, const char *text);
@@ -512,8 +556,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
int PositionAfterArea(PRectangle rcArea);
void StyleToPositionInView(Position pos);
- void IdleStyling();
- virtual void QueueStyling(int upTo);
+ virtual void IdleWork();
+ virtual void QueueIdleWork(WorkNeeded::workItems items, int upTo=0);
virtual bool PaintContains(PRectangle rc);
bool PaintContainsMargin();
diff --git a/plugins/scintilla/scintilla/src/Indicator.cxx b/plugins/scintilla/scintilla/src/Indicator.cxx
index 9ea4024..da75cbb 100644
--- a/plugins/scintilla/scintilla/src/Indicator.cxx
+++ b/plugins/scintilla/scintilla/src/Indicator.cxx
@@ -18,19 +18,49 @@
using namespace Scintilla;
#endif
+static PRectangle PixelGridAlign(const PRectangle &rc) {
+ // Move left and right side to nearest pixel to avoid blurry visuals
+ return PRectangle(int(rc.left + 0.5), rc.top, int(rc.right + 0.5), rc.bottom);
+}
+
void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine) {
surface->PenColour(fore);
int ymid = (rc.bottom + rc.top) / 2;
if (style == INDIC_SQUIGGLE) {
- surface->MoveTo(rc.left, rc.top);
- int x = rc.left + 2;
- int y = 2;
- while (x < rc.right) {
+ int x = int(rc.left+0.5);
+ int xLast = int(rc.right+0.5);
+ int y = 0;
+ surface->MoveTo(x, rc.top + y);
+ while (x < xLast) {
+ if ((x + 2) > xLast) {
+ if (xLast > x)
+ y = 1;
+ x = xLast;
+ } else {
+ x += 2;
+ y = 2 - y;
+ }
surface->LineTo(x, rc.top + y);
- x += 2;
- y = 2 - y;
}
- surface->LineTo(rc.right, rc.top + y); // Finish the line
+ } else if (style == INDIC_SQUIGGLEPIXMAP) {
+ PRectangle rcSquiggle = PixelGridAlign(rc);
+
+ int width = Platform::Minimum(4000, rcSquiggle.Width());
+ RGBAImage image(width, 3, 1.0, 0);
+ enum { alphaFull = 0xff, alphaSide = 0x2f, alphaSide2=0x5f };
+ for (int x = 0; x < width; x++) {
+ if (x%2) {
+ // Two halfway columns have a full pixel in middle flanked by light pixels
+ image.SetPixel(x, 0, fore, alphaSide);
+ image.SetPixel(x, 1, fore, alphaFull);
+ image.SetPixel(x, 2, fore, alphaSide);
+ } else {
+ // Extreme columns have a full pixel at bottom or top and a mid-tone pixel in
centre
+ image.SetPixel(x, (x%4) ? 0 : 2, fore, alphaFull);
+ image.SetPixel(x, 1, fore, alphaSide2);
+ }
+ }
+ surface->DrawRGBAImage(rcSquiggle, image.GetWidth(), image.GetHeight(), image.Pixels());
} else if (style == INDIC_SQUIGGLELOW) {
surface->MoveTo(rc.left, rc.top);
int x = rc.left + 3;
@@ -89,13 +119,12 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
rcBox.right = rc.right;
surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore, fillAlpha, fore,
outlineAlpha, 0);
} else if (style == INDIC_DOTBOX) {
- PRectangle rcBox = rcLine;
+ PRectangle rcBox = PixelGridAlign(rc);
rcBox.top = rcLine.top + 1;
- rcBox.left = rc.left;
- rcBox.right = rc.right;
+ rcBox.bottom = rcLine.bottom;
// Cap width at 4000 to avoid large allocations when mistakes made
int width = Platform::Minimum(rcBox.Width(), 4000);
- RGBAImage image(width, rcBox.Height(), 0);
+ RGBAImage image(width, rcBox.Height(), 1.0, 0);
// Draw horizontal lines top and bottom
for (int x=0; x<width; x++) {
for (int y=0; y<rcBox.Height(); y += rcBox.Height()-1) {
diff --git a/plugins/scintilla/scintilla/src/LineMarker.cxx b/plugins/scintilla/scintilla/src/LineMarker.cxx
index 99e8326..94513f5 100644
--- a/plugins/scintilla/scintilla/src/LineMarker.cxx
+++ b/plugins/scintilla/scintilla/src/LineMarker.cxx
@@ -6,6 +6,7 @@
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
+#include <math.h>
#include <vector>
#include <map>
@@ -32,9 +33,9 @@ void LineMarker::SetXPM(const char *const *linesForm) {
markType = SC_MARK_PIXMAP;
}
-void LineMarker::SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage) {
+void LineMarker::SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage) {
delete image;
- image = new RGBAImage(sizeRGBAImage.x, sizeRGBAImage.y, pixelsRGBAImage);
+ image = new RGBAImage(sizeRGBAImage.x, sizeRGBAImage.y, scale, pixelsRGBAImage);
markType = SC_MARK_RGBAIMAGE;
}
@@ -99,10 +100,10 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
if ((markType == SC_MARK_RGBAIMAGE) && (image)) {
// Make rectangle just large enough to fit image centred on centre of rcWhole
PRectangle rcImage;
- rcImage.top = static_cast<int>(((rcWhole.top + rcWhole.bottom) - image->GetHeight()) / 2);
- rcImage.bottom = rcImage.top + image->GetHeight();
- rcImage.left = static_cast<int>(((rcWhole.left + rcWhole.right) - image->GetWidth()) / 2);
- rcImage.right = rcImage.left + image->GetWidth();
+ rcImage.top = static_cast<int>(((rcWhole.top + rcWhole.bottom) - image->GetScaledHeight()) /
2);
+ rcImage.bottom = rcImage.top + image->GetScaledHeight();
+ rcImage.left = static_cast<int>(((rcWhole.left + rcWhole.right) - image->GetScaledWidth()) /
2);
+ rcImage.right = rcImage.left + image->GetScaledWidth();
surface->DrawRGBAImage(rcImage, image->GetWidth(), image->GetHeight(), image->Pixels());
return;
}
@@ -112,8 +113,8 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
rc.bottom--;
int minDim = Platform::Minimum(rc.Width(), rc.Height());
minDim--; // Ensure does not go beyond edge
- int centreX = (rc.right + rc.left) / 2;
- int centreY = (rc.bottom + rc.top) / 2;
+ int centreX = floor((rc.right + rc.left) / 2.0);
+ int centreY = floor((rc.bottom + rc.top) / 2.0);
int dimOn2 = minDim / 2;
int dimOn4 = minDim / 4;
int blobSize = dimOn2-1;
diff --git a/plugins/scintilla/scintilla/src/LineMarker.h b/plugins/scintilla/scintilla/src/LineMarker.h
index 5c73a62..e226ef5 100644
--- a/plugins/scintilla/scintilla/src/LineMarker.h
+++ b/plugins/scintilla/scintilla/src/LineMarker.h
@@ -66,7 +66,7 @@ public:
}
void SetXPM(const char *textForm);
void SetXPM(const char *const *linesForm);
- void SetRGBAImage(Point sizeRGBAImage, const unsigned char *pixelsRGBAImage);
+ void SetRGBAImage(Point sizeRGBAImage, float scale, const unsigned char *pixelsRGBAImage);
void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold, int
marginStyle);
};
diff --git a/plugins/scintilla/scintilla/src/PerLine.cxx b/plugins/scintilla/scintilla/src/PerLine.cxx
index 0bdb602..a903d6f 100644
--- a/plugins/scintilla/scintilla/src/PerLine.cxx
+++ b/plugins/scintilla/scintilla/src/PerLine.cxx
@@ -99,7 +99,7 @@ void MarkerHandleSet::RemoveHandle(int handle) {
}
}
-bool MarkerHandleSet::RemoveNumber(int markerNum) {
+bool MarkerHandleSet::RemoveNumber(int markerNum, bool all) {
bool performedDeletion = false;
MarkerHandleNumber **pmhn = &root;
while (*pmhn) {
@@ -108,6 +108,8 @@ bool MarkerHandleSet::RemoveNumber(int markerNum) {
*pmhn = mhn->next;
delete mhn;
performedDeletion = true;
+ if (!all)
+ break;
} else {
pmhn = &((*pmhn)->next);
}
@@ -223,12 +225,7 @@ bool LineMarkers::DeleteMark(int line, int markerNum, bool all) {
delete markers[line];
markers[line] = NULL;
} else {
- bool performedDeletion = markers[line]->RemoveNumber(markerNum);
- someChanges = someChanges || performedDeletion;
- while (all && performedDeletion) {
- performedDeletion = markers[line]->RemoveNumber(markerNum);
- someChanges = someChanges || performedDeletion;
- }
+ someChanges = markers[line]->RemoveNumber(markerNum, all);
if (markers[line]->Length() == 0) {
delete markers[line];
markers[line] = NULL;
diff --git a/plugins/scintilla/scintilla/src/PerLine.h b/plugins/scintilla/scintilla/src/PerLine.h
index b43c52b..50ce1e5 100644
--- a/plugins/scintilla/scintilla/src/PerLine.h
+++ b/plugins/scintilla/scintilla/src/PerLine.h
@@ -37,7 +37,7 @@ public:
bool Contains(int handle) const;
bool InsertHandle(int handle, int markerNum);
void RemoveHandle(int handle);
- bool RemoveNumber(int markerNum);
+ bool RemoveNumber(int markerNum, bool all);
void CombineWith(MarkerHandleSet *other);
};
diff --git a/plugins/scintilla/scintilla/src/PositionCache.h b/plugins/scintilla/scintilla/src/PositionCache.h
index 08ecee1..ad3fffd 100644
--- a/plugins/scintilla/scintilla/src/PositionCache.h
+++ b/plugins/scintilla/scintilla/src/PositionCache.h
@@ -130,6 +130,8 @@ class BreakFinder {
int subBreak;
Document *pdoc;
void Insert(int val);
+ // Private so BreakFinder objects can not be copied
+ BreakFinder(const BreakFinder &);
public:
// If a whole run is longer than lengthStartSubdivision then subdivide
// into smaller runs at spaces or punctuation.
@@ -148,6 +150,8 @@ class PositionCache {
size_t size;
unsigned int clock;
bool allClear;
+ // Private so PositionCache objects can not be copied
+ PositionCache(const PositionCache &);
public:
PositionCache();
~PositionCache();
diff --git a/plugins/scintilla/scintilla/src/RESearch.cxx b/plugins/scintilla/scintilla/src/RESearch.cxx
index ffcc58d..87f2a69 100644
--- a/plugins/scintilla/scintilla/src/RESearch.cxx
+++ b/plugins/scintilla/scintilla/src/RESearch.cxx
@@ -788,7 +788,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
}
case CHR: /* ordinary char: locate it fast */
c = *(ap+1);
- while ((lp < endp) && (ci.CharAt(lp) != c))
+ while ((lp < endp) && (static_cast<unsigned char>(ci.CharAt(lp)) != c))
lp++;
if (lp >= endp) /* if EOS, fail, else fall thru. */
return 0;
diff --git a/plugins/scintilla/scintilla/src/RunStyles.cxx b/plugins/scintilla/scintilla/src/RunStyles.cxx
index 643d2fb..9c4e90a 100644
--- a/plugins/scintilla/scintilla/src/RunStyles.cxx
+++ b/plugins/scintilla/scintilla/src/RunStyles.cxx
@@ -205,6 +205,7 @@ void RunStyles::DeleteRange(int position, int deleteLength) {
if (runStart == runEnd) {
// Deleting from inside one run
starts->InsertText(runStart, -deleteLength);
+ RemoveRunIfEmpty(runStart);
} else {
runStart = SplitRun(position);
runEnd = SplitRun(end);
diff --git a/plugins/scintilla/scintilla/src/RunStyles.h b/plugins/scintilla/scintilla/src/RunStyles.h
index a3efd93..4e90969 100644
--- a/plugins/scintilla/scintilla/src/RunStyles.h
+++ b/plugins/scintilla/scintilla/src/RunStyles.h
@@ -23,6 +23,8 @@ private:
void RemoveRun(int run);
void RemoveRunIfEmpty(int run);
void RemoveRunIfSameAsPrevious(int run);
+ // Private so RunStyles objects can not be copied
+ RunStyles(const RunStyles &);
public:
RunStyles();
~RunStyles();
diff --git a/plugins/scintilla/scintilla/src/ScintillaBase.cxx
b/plugins/scintilla/scintilla/src/ScintillaBase.cxx
index 9d4f93c..4a0146f 100644
--- a/plugins/scintilla/scintilla/src/ScintillaBase.cxx
+++ b/plugins/scintilla/scintilla/src/ScintillaBase.cxx
@@ -202,6 +202,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
const char *typeSep = strchr(list, ac.GetTypesep());
int lenInsert = typeSep ?
static_cast<int>(typeSep-list) : static_cast<int>(strlen(list));
+ UndoGroup ug(pdoc);
if (ac.ignoreCase) {
SetEmptySelection(sel.MainCaret() - lenEntered);
pdoc->DeleteChars(sel.MainCaret(), lenEntered);
@@ -213,6 +214,7 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
pdoc->InsertString(sel.MainCaret(), list + lenEntered, lenInsert -
lenEntered);
SetEmptySelection(sel.MainCaret() + lenInsert - lenEntered);
}
+ ac.Cancel();
return;
}
}
@@ -225,8 +227,8 @@ void ScintillaBase::AutoCompleteStart(int lenEntered, const char *list) {
if (rcPopupBounds.Height() == 0)
rcPopupBounds = rcClient;
- int heightLB = 100;
- int widthLB = 100;
+ int heightLB = ac.heightLBDefault;
+ int widthLB = ac.widthLBDefault;
if (pt.x >= rcClient.right - widthLB) {
HorizontalScrollTo(xOffset + pt.x - rcClient.right + widthLB);
Redraw();
@@ -293,13 +295,8 @@ void ScintillaBase::AutoCompleteMove(int delta) {
}
void ScintillaBase::AutoCompleteMoveToCurrentWord() {
- char wordCurrent[1000];
- int i;
- int startWord = ac.posStart - ac.startLen;
- for (i = startWord; i < sel.MainCaret() && i - startWord < 1000; i++)
- wordCurrent[i - startWord] = pdoc->CharAt(i);
- wordCurrent[Platform::Minimum(i - startWord, 999)] = '\0';
- ac.Select(wordCurrent);
+ std::string wordCurrent = RangeText(ac.posStart - ac.startLen, sel.MainCaret());
+ ac.Select(wordCurrent.c_str());
}
void ScintillaBase::AutoCompleteCharacterAdded(char ch) {
@@ -328,15 +325,12 @@ void ScintillaBase::AutoCompleteCharacterDeleted() {
}
void ScintillaBase::AutoCompleteCompleted() {
- int item = ac.lb->GetSelection();
- char selected[1000];
- selected[0] = '\0';
- if (item != -1) {
- ac.lb->GetValue(item, selected, sizeof(selected));
- } else {
+ int item = ac.GetSelection();
+ if (item == -1) {
AutoCompleteCancel();
return;
}
+ const std::string selected = ac.GetValue(item);
ac.Show(false);
@@ -348,7 +342,7 @@ void ScintillaBase::AutoCompleteCompleted() {
Position firstPos = ac.posStart - ac.startLen;
scn.position = firstPos;
scn.lParam = firstPos;
- scn.text = selected;
+ scn.text = selected.c_str();
NotifyParent(scn);
if (!ac.Active())
@@ -369,8 +363,8 @@ void ScintillaBase::AutoCompleteCompleted() {
}
SetEmptySelection(ac.posStart);
if (item != -1) {
- pdoc->InsertCString(firstPos, selected);
- SetEmptySelection(firstPos + static_cast<int>(strlen(selected)));
+ pdoc->InsertCString(firstPos, selected.c_str());
+ SetEmptySelection(firstPos + static_cast<int>(selected.length()));
}
SetLastXChosen();
}
@@ -378,19 +372,17 @@ void ScintillaBase::AutoCompleteCompleted() {
int ScintillaBase::AutoCompleteGetCurrent() {
if (!ac.Active())
return -1;
- return ac.lb->GetSelection();
+ return ac.GetSelection();
}
int ScintillaBase::AutoCompleteGetCurrentText(char *buffer) {
if (ac.Active()) {
- int item = ac.lb->GetSelection();
- char selected[1000];
- selected[0] = '\0';
+ int item = ac.GetSelection();
if (item != -1) {
- ac.lb->GetValue(item, selected, sizeof(selected));
+ const std::string selected = ac.GetValue(item);
if (buffer != NULL)
- strcpy(buffer, selected);
- return static_cast<int>(strlen(selected));
+ strcpy(buffer, selected.c_str());
+ return static_cast<int>(selected.length());
}
}
if (buffer != NULL)
@@ -481,6 +473,7 @@ class LexState : public LexInterface {
const LexerModule *lexCurrent;
void SetLexerModule(const LexerModule *lex);
PropSetSimple props;
+ int interfaceVersion;
public:
int lexLanguage;
@@ -500,6 +493,15 @@ public:
const char *PropGet(const char *key) const;
int PropGetInt(const char *key, int defaultValue=0) const;
int PropGetExpanded(const char *key, char *result) const;
+
+ int LineEndTypesSupported();
+ int AllocateSubStyles(int styleBase, int numberStyles);
+ int SubStylesStart(int styleBase);
+ int SubStylesLength(int styleBase);
+ void FreeSubStyles();
+ void SetIdentifiers(int style, const char *identifiers);
+ int DistanceToSecondaryStyles();
+ const char *GetSubStyleBases();
};
#ifdef SCI_NAMESPACE
@@ -509,6 +511,7 @@ public:
LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
lexCurrent = 0;
performingStyle = false;
+ interfaceVersion = lvOriginal;
lexLanguage = SCLEX_CONTAINER;
}
@@ -532,9 +535,12 @@ void LexState::SetLexerModule(const LexerModule *lex) {
instance->Release();
instance = 0;
}
+ interfaceVersion = lvOriginal;
lexCurrent = lex;
- if (lexCurrent)
+ if (lexCurrent) {
instance = lexCurrent->Create();
+ interfaceVersion = instance->Version();
+ }
pdoc->LexerChanged();
}
}
@@ -639,6 +645,60 @@ int LexState::PropGetExpanded(const char *key, char *result) const {
return props.GetExpanded(key, result);
}
+int LexState::LineEndTypesSupported() {
+ if (instance && (interfaceVersion >= lvSubStyles)) {
+ return static_cast<ILexerWithSubStyles *>(instance)->LineEndTypesSupported();
+ }
+ return 0;
+}
+
+int LexState::AllocateSubStyles(int styleBase, int numberStyles) {
+ if (instance && (interfaceVersion >= lvSubStyles)) {
+ return static_cast<ILexerWithSubStyles *>(instance)->AllocateSubStyles(styleBase,
numberStyles);
+ }
+ return -1;
+}
+
+int LexState::SubStylesStart(int styleBase) {
+ if (instance && (interfaceVersion >= lvSubStyles)) {
+ return static_cast<ILexerWithSubStyles *>(instance)->SubStylesStart(styleBase);
+ }
+ return -1;
+}
+
+int LexState::SubStylesLength(int styleBase) {
+ if (instance && (interfaceVersion >= lvSubStyles)) {
+ return static_cast<ILexerWithSubStyles *>(instance)->SubStylesLength(styleBase);
+ }
+ return 0;
+}
+
+void LexState::FreeSubStyles() {
+ if (instance && (interfaceVersion >= lvSubStyles)) {
+ static_cast<ILexerWithSubStyles *>(instance)->FreeSubStyles();
+ }
+}
+
+void LexState::SetIdentifiers(int style, const char *identifiers) {
+ if (instance && (interfaceVersion >= lvSubStyles)) {
+ static_cast<ILexerWithSubStyles *>(instance)->SetIdentifiers(style, identifiers);
+ }
+}
+
+int LexState::DistanceToSecondaryStyles() {
+ if (instance && (interfaceVersion >= lvSubStyles)) {
+ return static_cast<ILexerWithSubStyles *>(instance)->DistanceToSecondaryStyles();
+ }
+ return 0;
+}
+
+const char *LexState::GetSubStyleBases() {
+ if (instance && (interfaceVersion >= lvSubStyles)) {
+ return static_cast<ILexerWithSubStyles *>(instance)->GetSubStyleBases();
+ }
+ return "";
+}
+
#endif
void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
@@ -899,6 +959,31 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
case SCI_DESCRIBEKEYWORDSETS:
return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
+ case SCI_GETLINEENDTYPESSUPPORTED:
+ return DocumentLexState()->LineEndTypesSupported();
+
+ case SCI_ALLOCATESUBSTYLES:
+ return DocumentLexState()->AllocateSubStyles(wParam, lParam);
+
+ case SCI_GETSUBSTYLESSTART:
+ return DocumentLexState()->SubStylesStart(wParam);
+
+ case SCI_GETSUBSTYLESLENGTH:
+ return DocumentLexState()->SubStylesLength(wParam);
+
+ case SCI_FREESUBSTYLES:
+ DocumentLexState()->FreeSubStyles();
+ break;
+
+ case SCI_SETIDENTIFIERS:
+ DocumentLexState()->SetIdentifiers(wParam, reinterpret_cast<const char *>(lParam));
+ break;
+
+ case SCI_DISTANCETOSECONDARYSTYLES:
+ return DocumentLexState()->DistanceToSecondaryStyles();
+
+ case SCI_GETSUBSTYLEBASES:
+ return StringResult(lParam, DocumentLexState()->GetSubStyleBases());
#endif
default:
diff --git a/plugins/scintilla/scintilla/src/UniConversion.h b/plugins/scintilla/scintilla/src/UniConversion.h
index 704f162..70e8a95 100644
--- a/plugins/scintilla/scintilla/src/UniConversion.h
+++ b/plugins/scintilla/scintilla/src/UniConversion.h
@@ -26,3 +26,16 @@ inline bool UTF8IsAscii(int ch) {
enum { UTF8MaskWidth=0x7, UTF8MaskInvalid=0x8 };
int UTF8Classify(const unsigned char *us, int len);
+
+// Line separator is U+2028 \xe2\x80\xa8
+// Paragraph separator is U+2029 \xe2\x80\xa9
+const int UTF8SeparatorLength = 3;
+inline bool UTF8IsSeparator(const unsigned char *us) {
+ return (us[0] == 0xe2) && (us[1] == 0x80) && ((us[2] == 0xa8) || (us[2] == 0xa9));
+}
+
+// NEL is U+0085 \xc2\x85
+const int UTF8NELLength = 2;
+inline bool UTF8IsNEL(const unsigned char *us) {
+ return (us[0] == 0xc2) && (us[1] == 0x85);
+}
diff --git a/plugins/scintilla/scintilla/src/ViewStyle.cxx b/plugins/scintilla/scintilla/src/ViewStyle.cxx
index a4894ef..9181d9b 100644
--- a/plugins/scintilla/scintilla/src/ViewStyle.cxx
+++ b/plugins/scintilla/scintilla/src/ViewStyle.cxx
@@ -6,6 +6,7 @@
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
+#include <assert.h>
#include <vector>
#include <map>
@@ -140,6 +141,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
// Can't just copy fontname as its lifetime is relative to its owning ViewStyle
styles[sty].fontName = fontNames.Save(source.styles[sty].fontName);
}
+ nextExtendedStyle = source.nextExtendedStyle;
for (int mrk=0; mrk<=MARKER_MAX; mrk++) {
markers[mrk] = source.markers[mrk];
}
@@ -180,6 +182,7 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
caretcolour = source.caretcolour;
additionalCaretColour = source.additionalCaretColour;
showCaretLineBackground = source.showCaretLineBackground;
+ alwaysShowCaretLineBackground = source.alwaysShowCaretLineBackground;
caretLineBackground = source.caretLineBackground;
caretLineAlpha = source.caretLineAlpha;
edgecolour = source.edgecolour;
@@ -190,11 +193,13 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
someStylesForceCase = false;
leftMarginWidth = source.leftMarginWidth;
rightMarginWidth = source.rightMarginWidth;
- for (int i=0; i < margins; i++) {
- ms[i] = source.ms[i];
+ for (int margin=0; margin <= SC_MAX_MARGIN; margin++) {
+ ms[margin] = source.ms[margin];
}
maskInLine = source.maskInLine;
fixedColumnWidth = source.fixedColumnWidth;
+ marginInside = source.marginInside;
+ textStart = source.textStart;
zoomLevel = source.zoomLevel;
viewWhitespace = source.viewWhitespace;
whitespaceSize = source.whitespaceSize;
@@ -224,6 +229,7 @@ void ViewStyle::Init(size_t stylesSize_) {
stylesSize = 0;
styles = NULL;
AllocStyles(stylesSize_);
+ nextExtendedStyle = 256;
fontNames.Clear();
ResetDefaultStyle();
@@ -274,6 +280,7 @@ void ViewStyle::Init(size_t stylesSize_) {
caretcolour = ColourDesired(0, 0, 0);
additionalCaretColour = ColourDesired(0x7f, 0x7f, 0x7f);
showCaretLineBackground = false;
+ alwaysShowCaretLineBackground = false;
caretLineBackground = ColourDesired(0xff, 0xff, 0);
caretLineAlpha = SC_ALPHA_NOALPHA;
edgecolour = ColourDesired(0xc0, 0xc0, 0xc0);
@@ -301,13 +308,15 @@ void ViewStyle::Init(size_t stylesSize_) {
ms[2].style = SC_MARGIN_SYMBOL;
ms[2].width = 0;
ms[2].mask = 0;
- fixedColumnWidth = leftMarginWidth;
+ marginInside = true;
+ fixedColumnWidth = marginInside ? leftMarginWidth : 0;
maskInLine = 0xffffffff;
- for (int margin=0; margin < margins; margin++) {
+ for (int margin=0; margin <= SC_MAX_MARGIN; margin++) {
fixedColumnWidth += ms[margin].width;
if (ms[margin].width > 0)
maskInLine &= ~ms[margin].mask;
}
+ textStart = marginInside ? fixedColumnWidth : leftMarginWidth;
zoomLevel = 0;
viewWhitespace = wsInvisible;
whitespaceSize = 1;
@@ -354,6 +363,7 @@ void ViewStyle::Refresh(Surface &surface) {
CreateFont(styles[j]);
}
+ assert(frFirst);
frFirst->Realise(surface, zoomLevel, technology);
for (unsigned int k=0; k<stylesSize; k++) {
@@ -381,13 +391,14 @@ void ViewStyle::Refresh(Surface &surface) {
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
- fixedColumnWidth = leftMarginWidth;
+ fixedColumnWidth = marginInside ? leftMarginWidth : 0;
maskInLine = 0xffffffff;
- for (int margin=0; margin < margins; margin++) {
+ for (int margin=0; margin <= SC_MAX_MARGIN; margin++) {
fixedColumnWidth += ms[margin].width;
if (ms[margin].width > 0)
maskInLine &= ~ms[margin].mask;
}
+ textStart = marginInside ? fixedColumnWidth : leftMarginWidth;
}
void ViewStyle::AllocStyles(size_t sizeNew) {
@@ -409,6 +420,16 @@ void ViewStyle::AllocStyles(size_t sizeNew) {
stylesSize = sizeNew;
}
+void ViewStyle::ReleaseAllExtendedStyles() {
+ nextExtendedStyle = 256;
+}
+
+int ViewStyle::AllocateExtendedStyles(int numberStyles) {
+ int startRange = static_cast<int>(nextExtendedStyle);
+ nextExtendedStyle += numberStyles;
+ return startRange;
+}
+
void ViewStyle::EnsureStyle(size_t index) {
if (index >= stylesSize) {
size_t sizeNew = stylesSize * 2;
@@ -467,4 +488,3 @@ void ViewStyle::CalcLargestMarkerHeight() {
}
}
}
-
diff --git a/plugins/scintilla/scintilla/src/ViewStyle.h b/plugins/scintilla/scintilla/src/ViewStyle.h
index 56d15d3..bd26613 100644
--- a/plugins/scintilla/scintilla/src/ViewStyle.h
+++ b/plugins/scintilla/scintilla/src/ViewStyle.h
@@ -32,6 +32,8 @@ private:
int size;
int max;
+ // Private so FontNames objects can not be copied
+ FontNames(const FontNames &);
public:
FontNames();
~FontNames();
@@ -65,6 +67,7 @@ public:
FontRealised *frFirst;
size_t stylesSize;
Style *styles;
+ size_t nextExtendedStyle;
LineMarker markers[MARKER_MAX + 1];
int largestMarkerHeight;
Indicator indicators[INDIC_MAX + 1];
@@ -101,12 +104,13 @@ public:
bool hotspotUnderline;
bool hotspotSingleLine;
/// Margins are ordered: Line Numbers, Selection Margin, Spacing Margin
- enum { margins=5 };
int leftMarginWidth; ///< Spacing margin on left of text
- int rightMarginWidth; ///< Spacing margin on left of text
+ int rightMarginWidth; ///< Spacing margin on right of text
int maskInLine; ///< Mask for markers to be put into text because there is nowhere for them to go in
margin
- MarginStyle ms[margins];
- int fixedColumnWidth;
+ MarginStyle ms[SC_MAX_MARGIN+1];
+ int fixedColumnWidth; ///< Total width of margins
+ bool marginInside; ///< true: margin included in text view, false: separate views
+ int textStart; ///< Starting x position of text within the view
int zoomLevel;
WhiteSpaceVisibility viewWhitespace;
int whitespaceSize;
@@ -115,6 +119,7 @@ public:
ColourDesired caretcolour;
ColourDesired additionalCaretColour;
bool showCaretLineBackground;
+ bool alwaysShowCaretLineBackground;
ColourDesired caretLineBackground;
int caretLineAlpha;
ColourDesired edgecolour;
@@ -141,6 +146,8 @@ public:
void CreateFont(const FontSpecification &fs);
void Refresh(Surface &surface);
void AllocStyles(size_t sizeNew);
+ void ReleaseAllExtendedStyles();
+ int AllocateExtendedStyles(int numberStyles);
void EnsureStyle(size_t index);
void ResetDefaultStyle();
void ClearStyles();
diff --git a/plugins/scintilla/scintilla/src/XPM.cxx b/plugins/scintilla/scintilla/src/XPM.cxx
index aeb94a9..7188c24 100644
--- a/plugins/scintilla/scintilla/src/XPM.cxx
+++ b/plugins/scintilla/scintilla/src/XPM.cxx
@@ -319,8 +319,8 @@ int XPMSet::GetWidth() {
return (width > 0) ? width : 0;
}
-RGBAImage::RGBAImage(int width_, int height_, const unsigned char *pixels_) :
- height(height_), width(width_) {
+RGBAImage::RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_) :
+ height(height_), width(width_), scale(scale_) {
if (pixels_) {
pixelBytes.assign(pixels_, pixels_ + CountBytes());
} else {
@@ -331,6 +331,7 @@ RGBAImage::RGBAImage(int width_, int height_, const unsigned char *pixels_) :
RGBAImage::RGBAImage(const XPM &xpm) {
height = xpm.GetHeight();
width = xpm.GetWidth();
+ scale = 1;
pixelBytes.resize(CountBytes());
for (int y=0; y<height; y++) {
for (int x=0; x<width; x++) {
@@ -356,10 +357,10 @@ const unsigned char *RGBAImage::Pixels() const {
void RGBAImage::SetPixel(int x, int y, ColourDesired colour, int alpha) {
unsigned char *pixel = &pixelBytes[0] + (y*width+x) * 4;
// RGBA
- pixel[0] = colour.GetRed();
- pixel[1] = colour.GetGreen();
- pixel[2] = colour.GetBlue();
- pixel[3] = alpha;
+ pixel[0] = static_cast<unsigned char>(colour.GetRed());
+ pixel[1] = static_cast<unsigned char>(colour.GetGreen());
+ pixel[2] = static_cast<unsigned char>(colour.GetBlue());
+ pixel[3] = static_cast<unsigned char>(alpha);
}
RGBAImageSet::RGBAImageSet() : height(-1), width(-1){
diff --git a/plugins/scintilla/scintilla/src/XPM.h b/plugins/scintilla/scintilla/src/XPM.h
index 77ab080..e047ca8 100644
--- a/plugins/scintilla/scintilla/src/XPM.h
+++ b/plugins/scintilla/scintilla/src/XPM.h
@@ -80,13 +80,17 @@ class RGBAImage {
RGBAImage &operator=(const RGBAImage &);
int height;
int width;
+ float scale;
std::vector<unsigned char> pixelBytes;
public:
- RGBAImage(int width_, int height_, const unsigned char *pixels_);
+ RGBAImage(int width_, int height_, float scale_, const unsigned char *pixels_);
RGBAImage(const XPM &xpm);
virtual ~RGBAImage();
int GetHeight() const { return height; }
int GetWidth() const { return width; }
+ float GetScale() const { return scale; }
+ float GetScaledHeight() const { return height / scale; }
+ float GetScaledWidth() const { return width / scale; }
int CountBytes() const;
const unsigned char *Pixels() const;
void SetPixel(int x, int y, ColourDesired colour, int alpha=0xff);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]