[anjuta-extras/gtk3] scintilla: Update scintilla with changeset 3662:1d1c06df8a2f using gtk+3
- From: Sebastien Granjoux <sgranjoux src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [anjuta-extras/gtk3] scintilla: Update scintilla with changeset 3662:1d1c06df8a2f using gtk+3
- Date: Wed, 25 May 2011 20:00:38 +0000 (UTC)
commit df10f78c31a5e4608e0a80681b0eb6dbd29715a6
Author: Sébastien Granjoux <seb sfo free fr>
Date: Sun May 22 18:42:46 2011 +0200
scintilla: Update scintilla with changeset 3662:1d1c06df8a2f using gtk+3
configure.ac | 10 +-
plugins/Makefile.am | 4 +-
plugins/scintilla/aneditor-indent.cxx | 4 +-
plugins/scintilla/aneditor-priv.h | 1 -
plugins/scintilla/aneditor.cxx | 14 +-
plugins/scintilla/scintilla/Accessor.cxx | 79 ++
plugins/scintilla/scintilla/Accessor.h | 35 +
plugins/scintilla/scintilla/AutoComplete.cxx | 15 +-
plugins/scintilla/scintilla/AutoComplete.h | 6 +-
plugins/scintilla/scintilla/CallTip.cxx | 9 +-
plugins/scintilla/scintilla/CallTip.h | 4 +-
plugins/scintilla/scintilla/Catalogue.cxx | 186 +++
plugins/scintilla/scintilla/Catalogue.h | 26 +
plugins/scintilla/scintilla/CellBuffer.cxx | 45 +-
plugins/scintilla/scintilla/CellBuffer.h | 21 +-
plugins/scintilla/scintilla/CharClassify.cxx | 38 +-
plugins/scintilla/scintilla/CharClassify.h | 15 +-
plugins/scintilla/scintilla/CharacterSet.cxx | 61 +
plugins/scintilla/scintilla/CharacterSet.h | 104 ++-
plugins/scintilla/scintilla/ContractionState.cxx | 21 +-
plugins/scintilla/scintilla/ContractionState.h | 1 +
plugins/scintilla/scintilla/Converter.h | 19 +-
plugins/scintilla/scintilla/Decoration.h | 4 +-
plugins/scintilla/scintilla/Document.cxx | 748 ++++++++--
plugins/scintilla/scintilla/Document.h | 167 ++-
plugins/scintilla/scintilla/DocumentAccessor.cxx | 199 ---
plugins/scintilla/scintilla/DocumentAccessor.h | 77 -
plugins/scintilla/scintilla/Editor.cxx | 1186 ++++++++++++----
plugins/scintilla/scintilla/Editor.h | 79 +-
plugins/scintilla/scintilla/ExternalLexer.cxx | 122 +--
plugins/scintilla/scintilla/ExternalLexer.h | 42 +-
plugins/scintilla/scintilla/Indicator.cxx | 4 +-
plugins/scintilla/scintilla/Indicator.h | 3 +-
plugins/scintilla/scintilla/KeyWords.cxx | 429 ------
plugins/scintilla/scintilla/LexA68k.cxx | 318 +++++
plugins/scintilla/scintilla/LexAPDL.cxx | 15 +-
plugins/scintilla/scintilla/LexASY.cxx | 27 +-
plugins/scintilla/scintilla/LexAU3.cxx | 135 +-
plugins/scintilla/scintilla/LexAVE.cxx | 19 +-
plugins/scintilla/scintilla/LexAbaqus.cxx | 15 +-
plugins/scintilla/scintilla/LexAccessor.h | 175 +++
plugins/scintilla/scintilla/LexAda.cxx | 14 +-
plugins/scintilla/scintilla/LexAsm.cxx | 338 +++++-
plugins/scintilla/scintilla/LexAsn1.cxx | 15 +-
plugins/scintilla/scintilla/LexBaan.cxx | 15 +-
plugins/scintilla/scintilla/LexBash.cxx | 280 +++-
plugins/scintilla/scintilla/LexBasic.cxx | 383 ++++--
plugins/scintilla/scintilla/LexBullant.cxx | 19 +-
plugins/scintilla/scintilla/LexCLW.cxx | 45 +-
plugins/scintilla/scintilla/LexCOBOL.cxx | 21 +-
plugins/scintilla/scintilla/LexCPP.cxx | 926 +++++++++++--
plugins/scintilla/scintilla/LexCSS.cxx | 35 +-
plugins/scintilla/scintilla/LexCaml.cxx | 29 +-
plugins/scintilla/scintilla/LexCmake.cxx | 18 +-
plugins/scintilla/scintilla/LexConf.cxx | 28 +-
plugins/scintilla/scintilla/LexCrontab.cxx | 24 +-
plugins/scintilla/scintilla/LexCsound.cxx | 24 +-
plugins/scintilla/scintilla/LexD.cxx | 289 +++-
plugins/scintilla/scintilla/LexEScript.cxx | 15 +-
plugins/scintilla/scintilla/LexEiffel.cxx | 17 +-
plugins/scintilla/scintilla/LexErlang.cxx | 26 +-
plugins/scintilla/scintilla/LexFlagship.cxx | 382 ++++--
plugins/scintilla/scintilla/LexForth.cxx | 19 +-
plugins/scintilla/scintilla/LexFortran.cxx | 19 +-
plugins/scintilla/scintilla/LexGAP.cxx | 17 +-
plugins/scintilla/scintilla/LexGen.py | 304 ++++
plugins/scintilla/scintilla/LexGui4Cli.cxx | 15 +-
plugins/scintilla/scintilla/LexHTML.cxx | 236 +++-
plugins/scintilla/scintilla/LexHaskell.cxx | 267 +++--
plugins/scintilla/scintilla/LexInno.cxx | 27 +-
plugins/scintilla/scintilla/LexKix.cxx | 15 +-
plugins/scintilla/scintilla/LexLisp.cxx | 19 +-
plugins/scintilla/scintilla/LexLout.cxx | 15 +-
plugins/scintilla/scintilla/LexLua.cxx | 59 +-
plugins/scintilla/scintilla/LexMMIXAL.cxx | 17 +-
plugins/scintilla/scintilla/LexMPT.cxx | 32 +-
plugins/scintilla/scintilla/LexMSSQL.cxx | 16 +-
plugins/scintilla/scintilla/LexMagik.cxx | 15 +-
plugins/scintilla/scintilla/LexMarkdown.cxx | 76 +-
plugins/scintilla/scintilla/LexMatlab.cxx | 15 +-
plugins/scintilla/scintilla/LexMetapost.cxx | 31 +-
plugins/scintilla/scintilla/LexModula.cxx | 743 ++++++++++
plugins/scintilla/scintilla/LexMySQL.cxx | 215 ++--
plugins/scintilla/scintilla/LexNimrod.cxx | 33 +-
plugins/scintilla/scintilla/LexNsis.cxx | 18 +-
plugins/scintilla/scintilla/LexOpal.cxx | 71 +-
plugins/scintilla/scintilla/LexOthers.cxx | 75 +-
plugins/scintilla/scintilla/LexPB.cxx | 15 +-
plugins/scintilla/scintilla/LexPLM.cxx | 15 +-
plugins/scintilla/scintilla/LexPOV.cxx | 15 +-
plugins/scintilla/scintilla/LexPS.cxx | 17 +-
plugins/scintilla/scintilla/LexPascal.cxx | 162 ++--
plugins/scintilla/scintilla/LexPerl.cxx | 1000 ++++++++------
plugins/scintilla/scintilla/LexPowerPro.cxx | 396 +++---
plugins/scintilla/scintilla/LexPowerShell.cxx | 44 +-
plugins/scintilla/scintilla/LexProgress.cxx | 19 +-
plugins/scintilla/scintilla/LexPython.cxx | 51 +-
plugins/scintilla/scintilla/LexR.cxx | 19 +-
plugins/scintilla/scintilla/LexRebol.cxx | 15 +-
plugins/scintilla/scintilla/LexRuby.cxx | 168 ++-
plugins/scintilla/scintilla/LexSML.cxx | 30 +-
plugins/scintilla/scintilla/LexSQL.cxx | 540 +++++++--
plugins/scintilla/scintilla/LexScriptol.cxx | 21 +-
plugins/scintilla/scintilla/LexSmalltalk.cxx | 33 +-
plugins/scintilla/scintilla/LexSorcus.cxx | 135 +-
plugins/scintilla/scintilla/LexSpecman.cxx | 13 +-
plugins/scintilla/scintilla/LexSpice.cxx | 14 +-
plugins/scintilla/scintilla/LexTACL.cxx | 15 +-
plugins/scintilla/scintilla/LexTADS3.cxx | 27 +-
plugins/scintilla/scintilla/LexTAL.cxx | 17 +-
plugins/scintilla/scintilla/LexTCL.cxx | 29 +-
plugins/scintilla/scintilla/LexTeX.cxx | 55 +-
plugins/scintilla/scintilla/LexTxt2tags.cxx | 480 +++++++
plugins/scintilla/scintilla/LexVB.cxx | 15 +-
plugins/scintilla/scintilla/LexVHDL.cxx | 60 +-
plugins/scintilla/scintilla/LexVerilog.cxx | 40 +-
plugins/scintilla/scintilla/LexYAML.cxx | 17 +-
plugins/scintilla/scintilla/LexerBase.cxx | 92 ++
plugins/scintilla/scintilla/LexerBase.h | 41 +
plugins/scintilla/scintilla/LexerModule.cxx | 121 ++
plugins/scintilla/scintilla/LexerModule.h | 82 ++
plugins/scintilla/scintilla/LexerNoExceptions.cxx | 68 +
plugins/scintilla/scintilla/LexerNoExceptions.h | 32 +
plugins/scintilla/scintilla/LexerSimple.cxx | 57 +
plugins/scintilla/scintilla/LexerSimple.h | 30 +
plugins/scintilla/scintilla/LineMarker.cxx | 140 ++-
plugins/scintilla/scintilla/LineMarker.h | 13 +-
plugins/scintilla/scintilla/Makefile.am | 51 +-
plugins/scintilla/scintilla/OptionSet.h | 142 ++
plugins/scintilla/scintilla/Partitioning.h | 7 +-
plugins/scintilla/scintilla/PerLine.cxx | 19 +-
plugins/scintilla/scintilla/PerLine.h | 4 +-
plugins/scintilla/scintilla/PlatGTK.cxx | 855 +++++++-----
plugins/scintilla/scintilla/PositionCache.cxx | 93 +-
plugins/scintilla/scintilla/PositionCache.h | 29 +-
.../scintilla/{PropSet.cxx => PropSetSimple.cxx} | 27 +-
plugins/scintilla/scintilla/PropSetSimple.h | 4 +-
plugins/scintilla/scintilla/RESearch.cxx | 98 +-
plugins/scintilla/scintilla/RunStyles.cxx | 4 +-
plugins/scintilla/scintilla/SVector.h | 14 +-
plugins/scintilla/scintilla/ScintillaBase.cxx | 301 +++--
plugins/scintilla/scintilla/ScintillaBase.h | 17 +-
plugins/scintilla/scintilla/ScintillaGTK.cxx | 1460 ++++++++++----------
plugins/scintilla/scintilla/Selection.cxx | 13 +-
plugins/scintilla/scintilla/Selection.h | 9 +-
plugins/scintilla/scintilla/SparseState.h | 110 ++
plugins/scintilla/scintilla/SplitVector.h | 29 +-
plugins/scintilla/scintilla/Style.cxx | 133 +-
plugins/scintilla/scintilla/Style.h | 64 +-
plugins/scintilla/scintilla/StyleContext.cxx | 9 +-
plugins/scintilla/scintilla/StyleContext.h | 51 +-
plugins/scintilla/scintilla/UniConversion.cxx | 16 +-
plugins/scintilla/scintilla/UniConversion.h | 3 +-
plugins/scintilla/scintilla/ViewStyle.cxx | 157 ++-
plugins/scintilla/scintilla/ViewStyle.h | 22 +
plugins/scintilla/scintilla/WindowAccessor.cxx | 191 ---
plugins/scintilla/scintilla/WordList.cxx | 205 +++
plugins/scintilla/scintilla/WordList.h | 41 +
plugins/scintilla/scintilla/XPM.cxx | 8 +-
plugins/scintilla/scintilla/XPM.h | 12 +-
plugins/scintilla/scintilla/include/HFacer.py | 1 +
plugins/scintilla/scintilla/include/ILexer.h | 69 +
plugins/scintilla/scintilla/include/Platform.h | 20 +-
plugins/scintilla/scintilla/include/SciLexer.h | 91 ++-
plugins/scintilla/scintilla/include/Scintilla.h | 104 +-
.../scintilla/scintilla/include/Scintilla.iface | 223 +++-
.../scintilla/scintilla/include/ScintillaWidget.h | 12 +-
plugins/scintilla/scintilla/lexers.make | 14 +
plugins/scintilla/scintilla/test-scintilla.cxx | 42 +-
plugins/scintilla/style-editor.c | 4 +-
plugins/scintilla/text_editor_cbs.c | 15 +-
171 files changed, 13135 insertions(+), 5605 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index 1ab6372..f722a3b 100644
--- a/configure.ac
+++ b/configure.ac
@@ -3,9 +3,9 @@ dnl Created by Anjuta application wizard.
AC_PREREQ(2.59)
-m4_define(anjuta_major_version, 2)
-m4_define(anjuta_minor_version, 32)
-m4_define(anjuta_micro_version, 1)
+m4_define(anjuta_major_version, 3)
+m4_define(anjuta_minor_version, 0)
+m4_define(anjuta_micro_version, 0)
m4_define(anjuta_nano_version, 0)
m4_define(anjuta_version, anjuta_major_version.anjuta_minor_version.anjuta_micro_version.anjuta_nano_version)
@@ -29,7 +29,7 @@ AC_LANG_C
ANJUTA_REQUIRED=anjuta_major_version.anjuta_minor_version.0
BINUTILS_REQUIRED=2.15.92
LIBGRAPHVIZ_REQUIRED=1.0
-GTK_REQUIRED=2.17.10
+GTK_REQUIRED=3.0.0
GLIB_REQUIRED=2.16.0
GCONF_REQUIRED=2.12.0
GNOME_REQUIRED=2.12.0
@@ -102,7 +102,7 @@ dnl maintainer mode
AM_MAINTAINER_MODE
dnl Check for libanjuta
-PKG_CHECK_MODULES(LIBANJUTA, [libanjuta-1.0 >= $ANJUTA_REQUIRED])
+PKG_CHECK_MODULES(LIBANJUTA, [libanjuta-3.0 >= $ANJUTA_REQUIRED])
dnl Check for libgnome
PKG_CHECK_MODULES(GNOME, libgnomecanvas-2.0 >= $GNOME_REQUIRED)
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index 4499e74..e49a311 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1 +1,3 @@
-SUBDIRS = valgrind scratchbox profiler scintilla sample1
+#SUBDIRS = valgrind scratchbox profiler scintilla sample1
+# Only the following plugins are supported on Gtk+3
+SUBDIRS = scratchbox scintilla sample1
diff --git a/plugins/scintilla/aneditor-indent.cxx b/plugins/scintilla/aneditor-indent.cxx
index 5fbddb9..9983ac3 100644
--- a/plugins/scintilla/aneditor-indent.cxx
+++ b/plugins/scintilla/aneditor-indent.cxx
@@ -90,11 +90,13 @@ int AnEditor::GetLineIndentPosition(int line) {
}
bool AnEditor::RangeIsAllWhitespace(int start, int end) {
- WindowAccessor acc(wEditor.GetID(), *props);
+ //FIXME WindowAccessor acc(wEditor.GetID(), *props);
+#if 0
for (int i = start;i < end;i++) {
if ((acc[i] != ' ') && (acc[i] != '\t'))
return false;
}
+#endif
return true;
}
diff --git a/plugins/scintilla/aneditor-priv.h b/plugins/scintilla/aneditor-priv.h
index 6867b0a..b31da0c 100644
--- a/plugins/scintilla/aneditor-priv.h
+++ b/plugins/scintilla/aneditor-priv.h
@@ -41,7 +41,6 @@
#include "Platform.h"
#include "PropSet.h"
#include "Accessor.h"
-#include "WindowAccessor.h"
#include "KeyWords.h"
#include "Scintilla.h"
#include "ScintillaWidget.h"
diff --git a/plugins/scintilla/aneditor.cxx b/plugins/scintilla/aneditor.cxx
index b5b92c7..7246059 100644
--- a/plugins/scintilla/aneditor.cxx
+++ b/plugins/scintilla/aneditor.cxx
@@ -118,7 +118,7 @@ AnEditor::AnEditor(PropSetFile* p) {
wEditor = scintilla_new();
g_object_ref (G_OBJECT (wEditor.GetID()));
- gtk_object_sink (GTK_OBJECT (wEditor.GetID()));
+ g_object_ref_sink (G_OBJECT (wEditor.GetID()));
scintilla_set_id(SCINTILLA(wEditor.GetID()), 0);
fnEditor = reinterpret_cast<SciFnDirect>(Platform::SendScintilla(
@@ -541,7 +541,8 @@ bool AnEditor::FindMatchingBracePosition(bool editor, int &braceAtCaret, int &br
braceOpposite = -1;
char charBefore = '\0';
char styleBefore = '\0';
- WindowAccessor acc(win.GetID(), *props);
+ //FIXME WindowAccessor acc(win.GetID(), *props);
+#if 0
if (caretPos > 0) {
charBefore = acc[caretPos - 1];
styleBefore = static_cast<char>(acc.StyleAt(caretPos - 1) & 31);
@@ -584,6 +585,7 @@ bool AnEditor::FindMatchingBracePosition(bool editor, int &braceAtCaret, int &br
isInside = !isAfter;
}
}
+#endif
return isInside;
}
@@ -644,7 +646,8 @@ void AnEditor::SelectionWord(char *word, int len) {
int selStart = cr.cpMin;
int selEnd = cr.cpMax;
if (selStart == selEnd) {
- WindowAccessor acc(wEditor.GetID(), *props);
+ //FIXME WindowAccessor acc(wEditor.GetID(), *props);
+#if 0
// Try and find a word at the caret
if (iswordcharforsel(acc[selStart])) {
while ((selStart > 0) && (iswordcharforsel(acc[selStart - 1])))
@@ -654,6 +657,7 @@ void AnEditor::SelectionWord(char *word, int len) {
if (selStart < selEnd)
selEnd++; // Because normal selections end one past
}
+#endif
}
word[0] = '\0';
if ((selStart < selEnd) && ((selEnd - selStart + 1) < len)) {
@@ -667,7 +671,8 @@ void AnEditor::WordSelect() {
int selEnd;
selStart = selEnd = SendEditor(SCI_GETCURRENTPOS);
- WindowAccessor acc(wEditor.GetID(), *props);
+ //FIXME WindowAccessor acc(wEditor.GetID(), *props);
+#if 0
if (iswordcharforsel(acc[selStart])) {
while ((selStart > 0) && (iswordcharforsel(acc[selStart - 1])))
selStart--;
@@ -676,6 +681,7 @@ void AnEditor::WordSelect() {
if (selStart < selEnd)
selEnd++; // Because normal selections end one past
}
+#endif
SetSelection(selStart, selEnd);
}
diff --git a/plugins/scintilla/scintilla/Accessor.cxx b/plugins/scintilla/scintilla/Accessor.cxx
new file mode 100644
index 0000000..5adaaa2
--- /dev/null
+++ b/plugins/scintilla/scintilla/Accessor.cxx
@@ -0,0 +1,79 @@
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+Accessor::Accessor(IDocument *pAccess_, PropSetSimple *pprops_) : LexAccessor(pAccess_), pprops(pprops_) {
+}
+
+int Accessor::GetPropertyInt(const char *key, int defaultValue) {
+ return pprops->GetInt(key, defaultValue);
+}
+
+int Accessor::IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader) {
+ int end = Length();
+ int spaceFlags = 0;
+
+ // Determines the indentation level of the current line and also checks for consistent
+ // indentation compared to the previous line.
+ // Indentation is judged consistent when the indentation whitespace of each line lines
+ // the same or the indentation of one line is a prefix of the other.
+
+ int pos = LineStart(line);
+ char ch = (*this)[pos];
+ int indent = 0;
+ bool inPrevPrefix = line > 0;
+ int posPrev = inPrevPrefix ? LineStart(line-1) : 0;
+ while ((ch == ' ' || ch == '\t') && (pos < end)) {
+ if (inPrevPrefix) {
+ char chPrev = (*this)[posPrev++];
+ if (chPrev == ' ' || chPrev == '\t') {
+ if (chPrev != ch)
+ spaceFlags |= wsInconsistent;
+ } else {
+ inPrevPrefix = false;
+ }
+ }
+ if (ch == ' ') {
+ spaceFlags |= wsSpace;
+ indent++;
+ } else { // Tab
+ spaceFlags |= wsTab;
+ if (spaceFlags & wsSpace)
+ spaceFlags |= wsSpaceTab;
+ indent = (indent / 8 + 1) * 8;
+ }
+ ch = (*this)[++pos];
+ }
+
+ *flags = spaceFlags;
+ indent += SC_FOLDLEVELBASE;
+ // if completely empty line or the start of a comment...
+ if ((ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r') ||
+ (pfnIsCommentLeader && (*pfnIsCommentLeader)(*this, pos, end-pos)))
+ return indent | SC_FOLDLEVELWHITEFLAG;
+ else
+ return indent;
+}
diff --git a/plugins/scintilla/scintilla/Accessor.h b/plugins/scintilla/scintilla/Accessor.h
new file mode 100644
index 0000000..2f28c1a
--- /dev/null
+++ b/plugins/scintilla/scintilla/Accessor.h
@@ -0,0 +1,35 @@
+// Scintilla source code edit control
+/** @file Accessor.h
+ ** Interfaces between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef ACCESSOR_H
+#define ACCESSOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+enum { wsSpace = 1, wsTab = 2, wsSpaceTab = 4, wsInconsistent=8};
+
+class Accessor;
+class WordList;
+class PropSetSimple;
+
+typedef bool (*PFNIsCommentLeader)(Accessor &styler, int pos, int len);
+
+class Accessor : public LexAccessor {
+public:
+ PropSetSimple *pprops;
+ Accessor(IDocument *pAccess_, PropSetSimple *pprops_);
+ int GetPropertyInt(const char *, int defaultValue=0);
+ int IndentAmount(int line, int *flags, PFNIsCommentLeader pfnIsCommentLeader = 0);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/AutoComplete.cxx b/plugins/scintilla/scintilla/AutoComplete.cxx
index 86c64df..f6a291f 100644
--- a/plugins/scintilla/scintilla/AutoComplete.cxx
+++ b/plugins/scintilla/scintilla/AutoComplete.cxx
@@ -8,10 +8,11 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <assert.h>
#include "Platform.h"
-#include "CharClassify.h"
+#include "CharacterSet.h"
#include "AutoComplete.h"
#ifdef SCI_NAMESPACE
@@ -43,12 +44,12 @@ AutoComplete::~AutoComplete() {
}
}
-bool AutoComplete::Active() {
+bool AutoComplete::Active() const {
return active;
}
-void AutoComplete::Start(Window &parent, int ctrlID,
- int position, Point location, int startLen_,
+void AutoComplete::Start(Window &parent, int ctrlID,
+ int position, Point location, int startLen_,
int lineHeight, bool unicodeMode) {
if (active) {
Cancel();
@@ -82,7 +83,7 @@ void AutoComplete::SetSeparator(char separator_) {
separator = separator_;
}
-char AutoComplete::GetSeparator() {
+char AutoComplete::GetSeparator() const {
return separator;
}
@@ -90,7 +91,7 @@ void AutoComplete::SetTypesep(char separator_) {
typesep = separator_;
}
-char AutoComplete::GetTypesep() {
+char AutoComplete::GetTypesep() const {
return typesep;
}
@@ -128,11 +129,11 @@ void AutoComplete::Select(const char *word) {
size_t lenWord = strlen(word);
int location = -1;
const int maxItemLen=1000;
- char item[maxItemLen];
int start = 0; // lower bound of the api array block to search
int end = lb->Length() - 1; // upper bound of the api array block to search
while ((start <= end) && (location == -1)) { // Binary searching loop
int pivot = (start + end) / 2;
+ char item[maxItemLen];
lb->GetValue(pivot, item, maxItemLen);
int cond;
if (ignoreCase)
diff --git a/plugins/scintilla/scintilla/AutoComplete.h b/plugins/scintilla/scintilla/AutoComplete.h
index b10cdce..f48cb05 100644
--- a/plugins/scintilla/scintilla/AutoComplete.h
+++ b/plugins/scintilla/scintilla/AutoComplete.h
@@ -36,7 +36,7 @@ public:
~AutoComplete();
/// Is the auto completion list displayed?
- bool Active();
+ bool Active() const;
/// Display the auto completion list positioned to be near a character position
void Start(Window &parent, int ctrlID, int position, Point location,
@@ -52,11 +52,11 @@ public:
/// The separator character is used when interpreting the list in SetList
void SetSeparator(char separator_);
- char GetSeparator();
+ char GetSeparator() const;
/// The typesep character is used for seperating the word from the type
void SetTypesep(char separator_);
- char GetTypesep();
+ char GetTypesep() const;
/// The list string contains a sequence of words separated by the separator character
void SetList(const char *list);
diff --git a/plugins/scintilla/scintilla/CallTip.cxx b/plugins/scintilla/scintilla/CallTip.cxx
index 3ea2d48..cdc30fc 100644
--- a/plugins/scintilla/scintilla/CallTip.cxx
+++ b/plugins/scintilla/scintilla/CallTip.cxx
@@ -29,6 +29,7 @@ CallTip::CallTip() {
rectUp = PRectangle(0,0,0,0);
rectDown = PRectangle(0,0,0,0);
lineHeight = 1;
+ offsetMain = 0;
startHighlight = 0;
endHighlight = 0;
tabSize = 0;
@@ -45,6 +46,8 @@ CallTip::CallTip() {
colourSel.desired = ColourDesired(0, 0, 0x80);
colourShade.desired = ColourDesired(0, 0, 0);
colourLight.desired = ColourDesired(0xc0, 0xc0, 0xc0);
+ codePage = 0;
+ clickPlace = 0;
}
CallTip::~CallTip() {
@@ -68,7 +71,7 @@ static bool IsArrowCharacter(char ch) {
}
// We ignore tabs unless a tab width has been set.
-bool CallTip::IsTabCharacter(char ch) {
+bool CallTip::IsTabCharacter(char ch) const {
return (tabSize > 0) && (ch == '\t');
}
@@ -95,9 +98,9 @@ void CallTip::DrawChunk(Surface *surface, int &x, const char *s,
int maxEnd = 0;
const int numEnds = 10;
int ends[numEnds + 2];
- for (int i=0;i<len;i++) {
+ for (int i=0; i<len; i++) {
if ((maxEnd < numEnds) &&
- (IsArrowCharacter(s[i]) || IsTabCharacter(s[i])) ) {
+ (IsArrowCharacter(s[i]) || IsTabCharacter(s[i]))) {
if (i > 0)
ends[maxEnd++] = i;
ends[maxEnd++] = i+1;
diff --git a/plugins/scintilla/scintilla/CallTip.h b/plugins/scintilla/scintilla/CallTip.h
index a64755f..a9ba82e 100644
--- a/plugins/scintilla/scintilla/CallTip.h
+++ b/plugins/scintilla/scintilla/CallTip.h
@@ -33,7 +33,7 @@ class CallTip {
int posStart, int posEnd, int ytext, PRectangle rcClient,
bool highlight, bool draw);
int PaintContents(Surface *surfaceWindow, bool draw);
- bool IsTabCharacter(char c);
+ bool IsTabCharacter(char c) const;
int NextTabPos(int x);
public:
@@ -61,7 +61,7 @@ public:
/// Setup the calltip and return a rectangle of the area required.
PRectangle CallTipStart(int pos, Point pt, const char *defn,
- const char *faceName, int size, int codePage_,
+ const char *faceName, int size, int codePage_,
int characterSet, Window &wParent);
void CallTipCancel();
diff --git a/plugins/scintilla/scintilla/Catalogue.cxx b/plugins/scintilla/scintilla/Catalogue.cxx
new file mode 100644
index 0000000..00785d5
--- /dev/null
+++ b/plugins/scintilla/scintilla/Catalogue.cxx
@@ -0,0 +1,186 @@
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+
+#include <vector>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "LexerModule.h"
+#include "Catalogue.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static std::vector<LexerModule *> lexerCatalogue;
+static int nextLanguage = SCLEX_AUTOMATIC+1;
+
+const LexerModule *Catalogue::Find(int language) {
+ Scintilla_LinkLexers();
+ for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
+ it != lexerCatalogue.end(); ++it) {
+ if ((*it)->GetLanguage() == language) {
+ return *it;
+ }
+ }
+ return 0;
+}
+
+const LexerModule *Catalogue::Find(const char *languageName) {
+ Scintilla_LinkLexers();
+ if (languageName) {
+ for (std::vector<LexerModule *>::iterator it=lexerCatalogue.begin();
+ it != lexerCatalogue.end(); ++it) {
+ if ((*it)->languageName && (0 == strcmp((*it)->languageName, languageName))) {
+ return *it;
+ }
+ }
+ }
+ return 0;
+}
+
+void Catalogue::AddLexerModule(LexerModule *plm) {
+ if (plm->GetLanguage() == SCLEX_AUTOMATIC) {
+ plm->language = nextLanguage;
+ nextLanguage++;
+ }
+ lexerCatalogue.push_back(plm);
+}
+
+// Alternative historical name for Scintilla_LinkLexers
+int wxForceScintillaLexers(void) {
+ return Scintilla_LinkLexers();
+}
+
+// To add or remove a lexer, add or remove its file and run LexGen.py.
+
+// Force a reference to all of the Scintilla lexers so that the linker will
+// not remove the code of the lexers.
+int Scintilla_LinkLexers() {
+
+ static int initialised = 0;
+ if (initialised)
+ return 0;
+ initialised = 1;
+
+// Shorten the code that declares a lexer and ensures it is linked in by calling a method.
+#define LINK_LEXER(lexer) extern LexerModule lexer; Catalogue::AddLexerModule(&lexer);
+
+//++Autogenerated -- run src/LexGen.py to regenerate
+//**\(\tLINK_LEXER(\*);\n\)
+ LINK_LEXER(lmA68k);
+ LINK_LEXER(lmAbaqus);
+ LINK_LEXER(lmAda);
+ LINK_LEXER(lmAns1);
+ LINK_LEXER(lmAPDL);
+ LINK_LEXER(lmAsm);
+ LINK_LEXER(lmASY);
+ LINK_LEXER(lmAU3);
+ LINK_LEXER(lmAVE);
+ LINK_LEXER(lmBaan);
+ LINK_LEXER(lmBash);
+ LINK_LEXER(lmBatch);
+ LINK_LEXER(lmBlitzBasic);
+ LINK_LEXER(lmBullant);
+ LINK_LEXER(lmCaml);
+ LINK_LEXER(lmClw);
+ LINK_LEXER(lmClwNoCase);
+ LINK_LEXER(lmCmake);
+ LINK_LEXER(lmCOBOL);
+ LINK_LEXER(lmConf);
+ LINK_LEXER(lmCPP);
+ LINK_LEXER(lmCPPNoCase);
+ LINK_LEXER(lmCsound);
+ LINK_LEXER(lmCss);
+ LINK_LEXER(lmD);
+ LINK_LEXER(lmDiff);
+ LINK_LEXER(lmEiffel);
+ LINK_LEXER(lmEiffelkw);
+ LINK_LEXER(lmErlang);
+ LINK_LEXER(lmErrorList);
+ LINK_LEXER(lmESCRIPT);
+ LINK_LEXER(lmF77);
+ LINK_LEXER(lmFlagShip);
+ LINK_LEXER(lmForth);
+ LINK_LEXER(lmFortran);
+ LINK_LEXER(lmFreeBasic);
+ LINK_LEXER(lmGAP);
+ LINK_LEXER(lmGui4Cli);
+ LINK_LEXER(lmHaskell);
+ LINK_LEXER(lmHTML);
+ LINK_LEXER(lmInno);
+ LINK_LEXER(lmKix);
+ LINK_LEXER(lmLatex);
+ LINK_LEXER(lmLISP);
+ LINK_LEXER(lmLot);
+ LINK_LEXER(lmLout);
+ LINK_LEXER(lmLua);
+ LINK_LEXER(lmMagikSF);
+ LINK_LEXER(lmMake);
+ LINK_LEXER(lmMarkdown);
+ LINK_LEXER(lmMatlab);
+ LINK_LEXER(lmMETAPOST);
+ LINK_LEXER(lmMMIXAL);
+ LINK_LEXER(lmModula);
+ LINK_LEXER(lmMSSQL);
+ LINK_LEXER(lmMySQL);
+ LINK_LEXER(lmNimrod);
+ LINK_LEXER(lmNncrontab);
+ LINK_LEXER(lmNsis);
+ LINK_LEXER(lmNull);
+ LINK_LEXER(lmOctave);
+ LINK_LEXER(lmOpal);
+ LINK_LEXER(lmPascal);
+ LINK_LEXER(lmPB);
+ LINK_LEXER(lmPerl);
+ LINK_LEXER(lmPHPSCRIPT);
+ LINK_LEXER(lmPLM);
+ LINK_LEXER(lmPo);
+ LINK_LEXER(lmPOV);
+ LINK_LEXER(lmPowerPro);
+ LINK_LEXER(lmPowerShell);
+ LINK_LEXER(lmProgress);
+ LINK_LEXER(lmProps);
+ LINK_LEXER(lmPS);
+ LINK_LEXER(lmPureBasic);
+ LINK_LEXER(lmPython);
+ LINK_LEXER(lmR);
+ LINK_LEXER(lmREBOL);
+ LINK_LEXER(lmRuby);
+ LINK_LEXER(lmScriptol);
+ LINK_LEXER(lmSmalltalk);
+ LINK_LEXER(lmSML);
+ LINK_LEXER(lmSorc);
+ LINK_LEXER(lmSpecman);
+ LINK_LEXER(lmSpice);
+ LINK_LEXER(lmSQL);
+ LINK_LEXER(lmTACL);
+ LINK_LEXER(lmTADS3);
+ LINK_LEXER(lmTAL);
+ LINK_LEXER(lmTCL);
+ LINK_LEXER(lmTeX);
+ LINK_LEXER(lmTxt2tags);
+ LINK_LEXER(lmVB);
+ LINK_LEXER(lmVBScript);
+ LINK_LEXER(lmVerilog);
+ LINK_LEXER(lmVHDL);
+ LINK_LEXER(lmXML);
+ LINK_LEXER(lmYAML);
+
+//--Autogenerated -- end of automatically generated section
+
+ return 1;
+}
diff --git a/plugins/scintilla/scintilla/Catalogue.h b/plugins/scintilla/scintilla/Catalogue.h
new file mode 100644
index 0000000..7fea37d
--- /dev/null
+++ b/plugins/scintilla/scintilla/Catalogue.h
@@ -0,0 +1,26 @@
+// Scintilla source code edit control
+/** @file Catalogue.h
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef CATALOGUE_H
+#define CATALOGUE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class Catalogue {
+public:
+ static const LexerModule *Find(int language);
+ static const LexerModule *Find(const char *languageName);
+ static void AddLexerModule(LexerModule *plm);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/CellBuffer.cxx b/plugins/scintilla/scintilla/CellBuffer.cxx
index be04403..19f6670 100644
--- a/plugins/scintilla/scintilla/CellBuffer.cxx
+++ b/plugins/scintilla/scintilla/CellBuffer.cxx
@@ -44,9 +44,11 @@ void LineVector::InsertText(int line, int delta) {
starts.InsertText(line, delta);
}
-void LineVector::InsertLine(int line, int position) {
+void LineVector::InsertLine(int line, int position, bool lineStart) {
starts.InsertPartition(line, position);
if (perLine) {
+ if ((line > 0) && lineStart)
+ line--;
perLine->InsertLine(line);
}
}
@@ -197,7 +199,7 @@ void UndoHistory::AppendAction(actionType at, int position, char *data, int leng
// Insertions must be immediately after to coalesce
currentAction++;
} else if (at == removeAction) {
- if ((lengthData == 1) || (lengthData == 2)){
+ if ((lengthData == 1) || (lengthData == 2)) {
if ((position + lengthData) == actPrevious->position) {
; // Backspace -> OK
} else if (position == actPrevious->position) {
@@ -339,7 +341,7 @@ char CellBuffer::CharAt(int position) const {
return substance.ValueAt(position);
}
-void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) {
+void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) const {
if (lengthRetrieve < 0)
return;
if (position < 0)
@@ -349,17 +351,27 @@ void CellBuffer::GetCharRange(char *buffer, int position, int lengthRetrieve) {
lengthRetrieve, substance.Length());
return;
}
-
- for (int i=0; i<lengthRetrieve; i++) {
- *buffer++ = substance.ValueAt(position + i);
- }
+ substance.GetRange(buffer, position, lengthRetrieve);
}
-char CellBuffer::StyleAt(int position) {
+char CellBuffer::StyleAt(int position) const {
return style.ValueAt(position);
}
-const char *CellBuffer::BufferPointer() {
+void CellBuffer::GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const {
+ if (lengthRetrieve < 0)
+ return;
+ if (position < 0)
+ return;
+ if ((position + lengthRetrieve) > style.Length()) {
+ Platform::DebugPrintf("Bad GetStyleRange %d for %d of %d\n", position,
+ lengthRetrieve, style.Length());
+ return;
+ }
+ style.GetRange(reinterpret_cast<char *>(buffer), position, lengthRetrieve);
+}
+
+const char *CellBuffer::BufferPointer() {
return substance.BufferPointer();
}
@@ -455,7 +467,7 @@ int CellBuffer::LineStart(int line) const {
return lv.LineStart(line);
}
-bool CellBuffer::IsReadOnly() {
+bool CellBuffer::IsReadOnly() const {
return readOnly;
}
@@ -473,8 +485,8 @@ bool CellBuffer::IsSavePoint() {
// Without undo
-void CellBuffer::InsertLine(int line, int position) {
- lv.InsertLine(line, position);
+void CellBuffer::InsertLine(int line, int position, bool lineStart) {
+ lv.InsertLine(line, position, lineStart);
}
void CellBuffer::RemoveLine(int line) {
@@ -490,27 +502,28 @@ void CellBuffer::BasicInsertString(int position, const char *s, int insertLength
style.InsertValue(position, insertLength, 0);
int lineInsert = lv.LineFromPosition(position) + 1;
+ 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);
if (chPrev == '\r' && chAfter == '\n') {
// Splitting up a crlf pair at position
- InsertLine(lineInsert, position);
+ InsertLine(lineInsert, position, false);
lineInsert++;
}
char ch = ' ';
for (int i = 0; i < insertLength; i++) {
ch = s[i];
if (ch == '\r') {
- InsertLine(lineInsert, (position + i) + 1);
+ 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);
+ InsertLine(lineInsert, (position + i) + 1, atLineStart);
lineInsert++;
}
}
@@ -586,7 +599,7 @@ bool CellBuffer::SetUndoCollection(bool collectUndo) {
return collectingUndo;
}
-bool CellBuffer::IsCollectingUndo() {
+bool CellBuffer::IsCollectingUndo() const {
return collectingUndo;
}
diff --git a/plugins/scintilla/scintilla/CellBuffer.h b/plugins/scintilla/scintilla/CellBuffer.h
index 3381c19..a82a397 100644
--- a/plugins/scintilla/scintilla/CellBuffer.h
+++ b/plugins/scintilla/scintilla/CellBuffer.h
@@ -37,7 +37,7 @@ public:
void SetPerLine(PerLine *pl);
void InsertText(int line, int delta);
- void InsertLine(int line, int position);
+ void InsertLine(int line, int position, bool lineStart);
void SetLineStart(int line, int position);
void RemoveLine(int line);
int Lines() const {
@@ -142,6 +142,10 @@ private:
LineVector lv;
+ /// Actions without undo
+ void BasicInsertString(int position, const char *s, int insertLength);
+ void BasicDeleteChars(int position, int deleteLength);
+
public:
CellBuffer();
@@ -149,8 +153,9 @@ public:
/// Retrieving positions outside the range of the buffer works and returns 0
char CharAt(int position) const;
- void GetCharRange(char *buffer, int position, int lengthRetrieve);
- char StyleAt(int position);
+ void GetCharRange(char *buffer, int position, int lengthRetrieve) const;
+ char StyleAt(int position) const;
+ void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const;
const char *BufferPointer();
int Length() const;
@@ -159,7 +164,7 @@ public:
int Lines() const;
int LineStart(int line) const;
int LineFromPosition(int pos) const { return lv.LineFromPosition(pos); }
- void InsertLine(int line, int position);
+ void InsertLine(int line, int position, bool lineStart);
void RemoveLine(int line);
const char *InsertString(int position, const char *s, int insertLength, bool &startSequence);
@@ -170,7 +175,7 @@ public:
const char *DeleteChars(int position, int deleteLength, bool &startSequence);
- bool IsReadOnly();
+ bool IsReadOnly() const;
void SetReadOnly(bool set);
/// The save point is a marker in the undo stack where the container has stated that
@@ -178,12 +183,8 @@ public:
void SetSavePoint();
bool IsSavePoint();
- /// Actions without undo
- void BasicInsertString(int position, const char *s, int insertLength);
- void BasicDeleteChars(int position, int deleteLength);
-
bool SetUndoCollection(bool collectUndo);
- bool IsCollectingUndo();
+ bool IsCollectingUndo() const;
void BeginUndoAction();
void EndUndoAction();
void AddUndoAction(int token, bool mayCoalesce);
diff --git a/plugins/scintilla/scintilla/CharClassify.cxx b/plugins/scintilla/scintilla/CharClassify.cxx
index bbd25a0..c16af45 100644
--- a/plugins/scintilla/scintilla/CharClassify.cxx
+++ b/plugins/scintilla/scintilla/CharClassify.cxx
@@ -10,6 +10,10 @@
#include "CharClassify.h"
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
// Shut up annoying Visual C++ warnings:
#ifdef _MSC_VER
#pragma warning(disable: 4514)
@@ -42,37 +46,3 @@ void CharClassify::SetCharClasses(const unsigned char *chars, cc newCharClass) {
}
}
}
-
-int CompareCaseInsensitive(const char *a, const char *b) {
- while (*a && *b) {
- if (*a != *b) {
- char upperA = MakeUpperCase(*a);
- char upperB = MakeUpperCase(*b);
- if (upperA != upperB)
- return upperA - upperB;
- }
- a++;
- b++;
- }
- // Either *a or *b is nul
- return *a - *b;
-}
-
-int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
- while (*a && *b && len) {
- if (*a != *b) {
- char upperA = MakeUpperCase(*a);
- char upperB = MakeUpperCase(*b);
- if (upperA != upperB)
- return upperA - upperB;
- }
- a++;
- b++;
- len--;
- }
- if (len == 0)
- return 0;
- else
- // Either *a or *b is nul
- return *a - *b;
-}
diff --git a/plugins/scintilla/scintilla/CharClassify.h b/plugins/scintilla/scintilla/CharClassify.h
index d746fe0..e8b798e 100644
--- a/plugins/scintilla/scintilla/CharClassify.h
+++ b/plugins/scintilla/scintilla/CharClassify.h
@@ -8,6 +8,10 @@
#ifndef CHARCLASSIFY_H
#define CHARCLASSIFY_H
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
class CharClassify {
public:
CharClassify();
@@ -23,15 +27,8 @@ private:
unsigned char charClass[maxChar]; // not type cc to save space
};
-// These functions are implemented because each platform calls them something different.
-int CompareCaseInsensitive(const char *a, const char *b);
-int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
-
-inline char MakeUpperCase(char ch) {
- if (ch < 'a' || ch > 'z')
- return ch;
- else
- return static_cast<char>(ch - 'a' + 'A');
+#ifdef SCI_NAMESPACE
}
+#endif
#endif
diff --git a/plugins/scintilla/scintilla/CharacterSet.cxx b/plugins/scintilla/scintilla/CharacterSet.cxx
new file mode 100644
index 0000000..35669df
--- /dev/null
+++ b/plugins/scintilla/scintilla/CharacterSet.cxx
@@ -0,0 +1,61 @@
+// Scintilla source code edit control
+/** @file CharacterSet.cxx
+ ** Simple case functions for ASCII.
+ ** Lexer infrastructure.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <assert.h>
+
+#include "CharacterSet.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+int CompareCaseInsensitive(const char *a, const char *b) {
+ while (*a && *b) {
+ if (*a != *b) {
+ char upperA = MakeUpperCase(*a);
+ char upperB = MakeUpperCase(*b);
+ if (upperA != upperB)
+ return upperA - upperB;
+ }
+ a++;
+ b++;
+ }
+ // Either *a or *b is nul
+ return *a - *b;
+}
+
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len) {
+ while (*a && *b && len) {
+ if (*a != *b) {
+ char upperA = MakeUpperCase(*a);
+ char upperB = MakeUpperCase(*b);
+ if (upperA != upperB)
+ return upperA - upperB;
+ }
+ a++;
+ b++;
+ len--;
+ }
+ if (len == 0)
+ return 0;
+ else
+ // Either *a or *b is nul
+ return *a - *b;
+}
+
+#ifdef SCI_NAMESPACE
+}
+#endif
diff --git a/plugins/scintilla/scintilla/CharacterSet.h b/plugins/scintilla/scintilla/CharacterSet.h
index 4e8ffbd..ba42ea3 100644
--- a/plugins/scintilla/scintilla/CharacterSet.h
+++ b/plugins/scintilla/scintilla/CharacterSet.h
@@ -5,6 +5,13 @@
// Copyright 2007 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
+#ifndef CHARACTERSET_H
+#define CHARACTERSET_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
class CharacterSet {
int size;
bool valueAfter;
@@ -39,20 +46,103 @@ public:
size = 0;
}
void Add(int val) {
- PLATFORM_ASSERT(val >= 0);
- PLATFORM_ASSERT(val < size);
+ assert(val >= 0);
+ assert(val < size);
bset[val] = true;
}
- void AddString(const char *CharacterSet) {
- for (const char *cp=CharacterSet; *cp; cp++) {
+ void AddString(const char *setToAdd) {
+ for (const char *cp=setToAdd; *cp; cp++) {
int val = static_cast<unsigned char>(*cp);
- PLATFORM_ASSERT(val >= 0);
- PLATFORM_ASSERT(val < size);
+ assert(val >= 0);
+ assert(val < size);
bset[val] = true;
}
}
bool Contains(int val) const {
- PLATFORM_ASSERT(val >= 0);
+ assert(val >= 0);
+ if (val < 0) return false;
return (val < size) ? bset[val] : valueAfter;
}
};
+
+// Functions for classifying characters
+
+inline bool IsASpace(int ch) {
+ return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+inline bool IsASpaceOrTab(int ch) {
+ return (ch == ' ') || (ch == '\t');
+}
+
+inline bool IsADigit(int ch) {
+ return (ch >= '0') && (ch <= '9');
+}
+
+inline bool IsADigit(int ch, int base) {
+ if (base <= 10) {
+ return (ch >= '0') && (ch < '0' + base);
+ } else {
+ return ((ch >= '0') && (ch <= '9')) ||
+ ((ch >= 'A') && (ch < 'A' + base - 10)) ||
+ ((ch >= 'a') && (ch < 'a' + base - 10));
+ }
+}
+
+inline bool IsASCII(int ch) {
+ return ch < 0x80;
+}
+
+inline bool IsAlphaNumeric(int ch) {
+ return
+ ((ch >= '0') && (ch <= '9')) ||
+ ((ch >= 'a') && (ch <= 'z')) ||
+ ((ch >= 'A') && (ch <= 'Z'));
+}
+
+/**
+ * Check if a character is a space.
+ * This is ASCII specific but is safe with chars >= 0x80.
+ */
+inline bool isspacechar(int ch) {
+ return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
+}
+
+inline bool iswordchar(int ch) {
+ return IsASCII(ch) && (IsAlphaNumeric(ch) || ch == '.' || ch == '_');
+}
+
+inline bool iswordstart(int ch) {
+ return IsASCII(ch) && (IsAlphaNumeric(ch) || ch == '_');
+}
+
+inline bool isoperator(int ch) {
+ if (IsASCII(ch) && IsAlphaNumeric(ch))
+ return false;
+ if (ch == '%' || ch == '^' || ch == '&' || ch == '*' ||
+ ch == '(' || ch == ')' || ch == '-' || ch == '+' ||
+ ch == '=' || ch == '|' || ch == '{' || ch == '}' ||
+ ch == '[' || ch == ']' || ch == ':' || ch == ';' ||
+ ch == '<' || ch == '>' || ch == ',' || ch == '/' ||
+ ch == '?' || ch == '!' || ch == '.' || ch == '~')
+ return true;
+ return false;
+}
+
+// Simple case functions for ASCII.
+
+inline char MakeUpperCase(char ch) {
+ if (ch < 'a' || ch > 'z')
+ return ch;
+ else
+ return static_cast<char>(ch - 'a' + 'A');
+}
+
+int CompareCaseInsensitive(const char *a, const char *b);
+int CompareNCaseInsensitive(const char *a, const char *b, size_t len);
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/ContractionState.cxx b/plugins/scintilla/scintilla/ContractionState.cxx
index 08de5cf..8a1b486 100644
--- a/plugins/scintilla/scintilla/ContractionState.cxx
+++ b/plugins/scintilla/scintilla/ContractionState.cxx
@@ -193,6 +193,23 @@ bool ContractionState::SetExpanded(int lineDoc, bool expanded_) {
}
}
+int ContractionState::ContractedNext(int lineDocStart) const {
+ if (OneToOne()) {
+ return -1;
+ } else {
+ Check();
+ if (!expanded->ValueAt(lineDocStart)) {
+ return lineDocStart;
+ } else {
+ int lineDocNextChange = expanded->EndRun(lineDocStart);
+ if (lineDocNextChange < LinesInDoc())
+ return lineDocNextChange;
+ else
+ return -1;
+ }
+ }
+}
+
int ContractionState::GetHeight(int lineDoc) const {
if (OneToOne()) {
return 1;
@@ -232,11 +249,11 @@ void ContractionState::ShowAll() {
void ContractionState::Check() const {
#ifdef CHECK_CORRECTNESS
- for (int vline = 0;vline < LinesDisplayed(); vline++) {
+ for (int vline = 0; vline < LinesDisplayed(); vline++) {
const int lineDoc = DocFromDisplay(vline);
PLATFORM_ASSERT(GetVisible(lineDoc));
}
- for (int lineDoc = 0;lineDoc < LinesInDoc(); lineDoc++) {
+ for (int lineDoc = 0; lineDoc < LinesInDoc(); lineDoc++) {
const int displayThis = DisplayFromDoc(lineDoc);
const int displayNext = DisplayFromDoc(lineDoc + 1);
const int height = displayNext - displayThis;
diff --git a/plugins/scintilla/scintilla/ContractionState.h b/plugins/scintilla/scintilla/ContractionState.h
index ba62975..8e7b39b 100644
--- a/plugins/scintilla/scintilla/ContractionState.h
+++ b/plugins/scintilla/scintilla/ContractionState.h
@@ -51,6 +51,7 @@ public:
bool GetExpanded(int lineDoc) const;
bool SetExpanded(int lineDoc, bool expanded);
+ int ContractedNext(int lineDocStart) const;
int GetHeight(int lineDoc) const;
bool SetHeight(int lineDoc, int height);
diff --git a/plugins/scintilla/scintilla/Converter.h b/plugins/scintilla/scintilla/Converter.h
index d3038a2..8e7e3e9 100644
--- a/plugins/scintilla/scintilla/Converter.h
+++ b/plugins/scintilla/scintilla/Converter.h
@@ -3,12 +3,7 @@
// Copyright 2004 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
-#include <iconv.h>
-#if GTK_MAJOR_VERSION >= 2
- typedef GIConv ConverterHandle;
-#else
- typedef iconv_t ConverterHandle;
-#endif
+typedef GIConv ConverterHandle;
const ConverterHandle iconvhBad = (ConverterHandle)(-1);
// Since various versions of iconv can not agree on whether the src argument
// is char ** or const char ** provide a templatised adaptor.
@@ -24,11 +19,7 @@ size_t iconv_adaptor(size_t(*f_iconv)(ConverterHandle, T, size_t *, char **, siz
class Converter {
ConverterHandle iconvh;
void OpenHandle(const char *fullDestination, const char *charSetSource) {
-#if GTK_MAJOR_VERSION >= 2
iconvh = g_iconv_open(fullDestination, charSetSource);
-#else
- iconvh = iconv_open(fullDestination, charSetSource);
-#endif
}
bool Succeeded() const {
return iconvh != iconvhBad;
@@ -65,11 +56,7 @@ public:
}
void Close() {
if (Succeeded()) {
-#if GTK_MAJOR_VERSION >= 2
g_iconv_close(iconvh);
-#else
- iconv_close(iconvh);
-#endif
iconvh = iconvhBad;
}
}
@@ -77,11 +64,7 @@ public:
if (!Succeeded()) {
return (size_t)(-1);
} else {
-#if GTK_MAJOR_VERSION >= 2
return iconv_adaptor(g_iconv, iconvh, src, srcleft, dst, dstleft);
-#else
- return iconv_adaptor(iconv, iconvh, src, srcleft, dst, dstleft);
-#endif
}
}
};
diff --git a/plugins/scintilla/scintilla/Decoration.h b/plugins/scintilla/scintilla/Decoration.h
index 2809641..fedff97 100644
--- a/plugins/scintilla/scintilla/Decoration.h
+++ b/plugins/scintilla/scintilla/Decoration.h
@@ -40,10 +40,10 @@ public:
~DecorationList();
void SetCurrentIndicator(int indicator);
- int GetCurrentIndicator() { return currentIndicator; }
+ int GetCurrentIndicator() const { return currentIndicator; }
void SetCurrentValue(int value);
- int GetCurrentValue() { return currentValue; }
+ int GetCurrentValue() const { return currentValue; }
// Returns true if some values may have changed
bool FillRange(int &position, int value, int &fillLength);
diff --git a/plugins/scintilla/scintilla/Document.cxx b/plugins/scintilla/scintilla/Document.cxx
index a5d1adb..7b718f2 100644
--- a/plugins/scintilla/scintilla/Document.cxx
+++ b/plugins/scintilla/scintilla/Document.cxx
@@ -2,26 +2,34 @@
/** @file Document.cxx
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <assert.h>
+
+#include <string>
+#include <vector>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
+
#include "SplitVector.h"
#include "Partitioning.h"
#include "RunStyles.h"
#include "CellBuffer.h"
#include "PerLine.h"
#include "CharClassify.h"
+#include "CharacterSet.h"
#include "Decoration.h"
#include "Document.h"
#include "RESearch.h"
+#include "UniConversion.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -48,9 +56,38 @@ static inline bool IsUpperCase(char ch) {
return isascii(ch) && isupper(ch);
}
+void LexInterface::Colourise(int start, int end) {
+ ElapsedTime et;
+ if (pdoc && instance && !performingStyle) {
+ // Protect against reentrance, which may occur, for example, when
+ // fold points are discovered while performing styling and the folding
+ // code looks for child lines which may trigger styling.
+ performingStyle = true;
+
+ int lengthDoc = pdoc->Length();
+ if (end == -1)
+ end = lengthDoc;
+ int len = end - start;
+
+ PLATFORM_ASSERT(len >= 0);
+ PLATFORM_ASSERT(start + len <= lengthDoc);
+
+ int styleStart = 0;
+ if (start > 0)
+ styleStart = pdoc->StyleAt(start - 1) & pdoc->stylingBitsMask;
+
+ if (len > 0) {
+ instance->Lex(start, len, styleStart, pdoc);
+ instance->Fold(start, len, styleStart, pdoc);
+ }
+
+ performingStyle = false;
+ }
+}
+
Document::Document() {
refCount = 0;
-#ifdef unix
+#ifdef __unix__
eolMode = SC_EOL_LF;
#else
eolMode = SC_EOL_CRLF;
@@ -83,6 +120,8 @@ Document::Document() {
perLineData[ldAnnotation] = new LineAnnotation();
cb.SetPerLine(this);
+
+ pli = 0;
}
Document::~Document() {
@@ -98,6 +137,8 @@ Document::~Document() {
lenWatchers = 0;
delete regex;
regex = 0;
+ delete pli;
+ pli = 0;
}
void Document::Init() {
@@ -140,13 +181,13 @@ void Document::SetSavePoint() {
NotifySavePoint(true);
}
-int Document::GetMark(int line) {
- return static_cast<LineMarkers*>(perLineData[ldMarkers])->MarkValue(line);
+int Document::GetMark(int line) {
+ return static_cast<LineMarkers *>(perLineData[ldMarkers])->MarkValue(line);
}
int Document::AddMark(int line, int markerNum) {
- if (line <= LinesTotal()) {
- int prev = static_cast<LineMarkers*>(perLineData[ldMarkers])->
+ if (line >= 0 && line <= LinesTotal()) {
+ int prev = static_cast<LineMarkers *>(perLineData[ldMarkers])->
AddMark(line, markerNum, LinesTotal());
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
@@ -157,42 +198,49 @@ int Document::AddMark(int line, int markerNum) {
}
void Document::AddMarkSet(int line, int valueSet) {
+ if (line < 0 || line > LinesTotal()) {
+ return;
+ }
unsigned int m = valueSet;
for (int i = 0; m; i++, m >>= 1)
if (m & 1)
- static_cast<LineMarkers*>(perLineData[ldMarkers])->
+ static_cast<LineMarkers *>(perLineData[ldMarkers])->
AddMark(line, i, LinesTotal());
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
}
void Document::DeleteMark(int line, int markerNum) {
- static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, false);
+ static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMark(line, markerNum, false);
DocModification mh(SC_MOD_CHANGEMARKER, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
}
void Document::DeleteMarkFromHandle(int markerHandle) {
- static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMarkFromHandle(markerHandle);
+ static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMarkFromHandle(markerHandle);
DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
mh.line = -1;
NotifyModified(mh);
}
void Document::DeleteAllMarks(int markerNum) {
+ bool someChanges = false;
for (int line = 0; line < LinesTotal(); line++) {
- static_cast<LineMarkers*>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true);
+ if (static_cast<LineMarkers *>(perLineData[ldMarkers])->DeleteMark(line, markerNum, true))
+ someChanges = true;
+ }
+ if (someChanges) {
+ DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
+ mh.line = -1;
+ NotifyModified(mh);
}
- DocModification mh(SC_MOD_CHANGEMARKER, 0, 0, 0, 0);
- mh.line = -1;
- NotifyModified(mh);
}
-int Document::LineFromHandle(int markerHandle) {
- return static_cast<LineMarkers*>(perLineData[ldMarkers])->LineFromHandle(markerHandle);
+int Document::LineFromHandle(int markerHandle) {
+ return static_cast<LineMarkers *>(perLineData[ldMarkers])->LineFromHandle(markerHandle);
}
-int Document::LineStart(int line) const {
+int SCI_METHOD Document::LineStart(int line) const {
return cb.LineStart(line);
}
@@ -209,7 +257,14 @@ int Document::LineEnd(int line) const {
}
}
-int Document::LineFromPosition(int pos) const {
+void SCI_METHOD Document::SetErrorStatus(int status) {
+ // Tell the watchers the lexer has changed.
+ for (int i = 0; i < lenWatchers; i++) {
+ watchers[i].watcher->NotifyErrorOccurred(this, watchers[i].userData, status);
+ }
+}
+
+int SCI_METHOD Document::LineFromPosition(int pos) const {
return cb.LineFromPosition(pos);
}
@@ -226,7 +281,7 @@ int Document::VCHomePosition(int position) const {
int startPosition = LineStart(line);
int endLine = LineEnd(line);
int startText = startPosition;
- while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t' ) )
+ while (startText < endLine && (cb.CharAt(startText) == ' ' || cb.CharAt(startText) == '\t'))
startText++;
if (position == startText)
return startPosition;
@@ -234,8 +289,8 @@ int Document::VCHomePosition(int position) const {
return startText;
}
-int Document::SetLevel(int line, int level) {
- int prev = static_cast<LineLevels*>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
+int SCI_METHOD Document::SetLevel(int line, int level) {
+ int prev = static_cast<LineLevels *>(perLineData[ldLevels])->SetLevel(line, level, LinesTotal());
if (prev != level) {
DocModification mh(SC_MOD_CHANGEFOLD | SC_MOD_CHANGEMARKER,
LineStart(line), 0, 0, 0, line);
@@ -246,12 +301,12 @@ int Document::SetLevel(int line, int level) {
return prev;
}
-int Document::GetLevel(int line) {
- return static_cast<LineLevels*>(perLineData[ldLevels])->GetLevel(line);
+int SCI_METHOD Document::GetLevel(int line) const {
+ return static_cast<LineLevels *>(perLineData[ldLevels])->GetLevel(line);
}
-void Document::ClearLevels() {
- static_cast<LineLevels*>(perLineData[ldLevels])->ClearLevels();
+void Document::ClearLevels() {
+ static_cast<LineLevels *>(perLineData[ldLevels])->ClearLevels();
}
static bool IsSubordinate(int levelStart, int levelTry) {
@@ -300,6 +355,110 @@ int Document::GetFoldParent(int line) {
}
}
+void Document::GetHighlightDelimiters(HighlightDelimiter &highlightDelimiter, int line, int topLine, int bottomLine) {
+ int noNeedToParseBefore = Platform::Minimum(line, topLine) - 1;
+ int noNeedToParseAfter = Platform::Maximum(line, bottomLine) + 1;
+ int endLine = LineFromPosition(Length());
+ int beginFoldBlock = noNeedToParseBefore;
+ int endFoldBlock = -1;
+ int beginMarginCorrectlyDrawnZone = noNeedToParseBefore;
+ int endMarginCorrectlyDrawnZone = noNeedToParseAfter;
+ int endOfTailOfWhiteFlag = -1; //endOfTailOfWhiteFlag points the last SC_FOLDLEVELWHITEFLAG if follow a fold block. Otherwise endOfTailOfWhiteFlag points end of fold block.
+ int level = GetLevel(line);
+ int levelNumber = -1;
+ int lineLookLevel = 0;
+ int lineLookLevelNumber = -1;
+ int lineLook = line;
+ bool beginFoldBlockFound = false;
+ bool endFoldBlockFound = false;
+ bool beginMarginCorrectlyDrawnZoneFound = false;
+ bool endMarginCorrectlyDrawnZoneFound = false;
+
+ /*******************************************************************************/
+ /* search backward (beginFoldBlock & beginMarginCorrectlyDrawnZone) */
+ /*******************************************************************************/
+ for (endOfTailOfWhiteFlag = line; (lineLook > noNeedToParseBefore || (lineLookLevel & SC_FOLDLEVELWHITEFLAG)) && (!beginFoldBlockFound || !beginMarginCorrectlyDrawnZoneFound); --lineLook) {
+ lineLookLevel = GetLevel(lineLook);
+ if (levelNumber != -1) {
+ lineLookLevelNumber = lineLookLevel & SC_FOLDLEVELNUMBERMASK;
+ if (!beginMarginCorrectlyDrawnZoneFound && (lineLookLevelNumber > levelNumber)) {
+ beginMarginCorrectlyDrawnZoneFound = true;
+ beginMarginCorrectlyDrawnZone = endOfTailOfWhiteFlag;
+ }
+ //find the last space line (SC_FOLDLEVELWHITEFLAG).
+ if (!beginMarginCorrectlyDrawnZoneFound && !(lineLookLevel & SC_FOLDLEVELWHITEFLAG)) {
+ endOfTailOfWhiteFlag = lineLook - 1;
+ }
+ if (!beginFoldBlockFound && (lineLookLevelNumber < levelNumber)) {
+ beginFoldBlockFound = true;
+ beginFoldBlock = lineLook;
+ if (!beginMarginCorrectlyDrawnZoneFound) {
+ beginMarginCorrectlyDrawnZoneFound = true;
+ beginMarginCorrectlyDrawnZone = lineLook - 1;
+ }
+ } else if (!beginFoldBlockFound && lineLookLevelNumber == SC_FOLDLEVELBASE) {
+ beginFoldBlockFound = true;
+ beginFoldBlock = -1;
+ }
+ } else if (!(lineLookLevel & SC_FOLDLEVELWHITEFLAG)) {
+ endOfTailOfWhiteFlag = lineLook - 1;
+ levelNumber = lineLookLevel & SC_FOLDLEVELNUMBERMASK;
+ if (lineLookLevel & SC_FOLDLEVELHEADERFLAG &&
+ //Managed the folding block when a fold header does not have any subordinate lines to fold away.
+ (levelNumber < (GetLevel(lineLook + 1) & SC_FOLDLEVELNUMBERMASK))) {
+ beginFoldBlockFound = true;
+ beginFoldBlock = lineLook;
+ beginMarginCorrectlyDrawnZoneFound = true;
+ beginMarginCorrectlyDrawnZone = endOfTailOfWhiteFlag;
+ levelNumber = GetLevel(lineLook + 1) & SC_FOLDLEVELNUMBERMASK;;
+ }
+ }
+ }
+
+ /****************************************************************************/
+ /* search forward (endStartBlock & endMarginCorrectlyDrawnZone) */
+ /****************************************************************************/
+ if (level & SC_FOLDLEVELHEADERFLAG) {
+ //ignore this line because this line is on first one of block.
+ lineLook = line + 1;
+ } else {
+ lineLook = line;
+ }
+ for (; lineLook < noNeedToParseAfter && (!endFoldBlockFound || !endMarginCorrectlyDrawnZoneFound); ++lineLook) {
+ lineLookLevel = GetLevel(lineLook);
+ lineLookLevelNumber = lineLookLevel & SC_FOLDLEVELNUMBERMASK;
+ if (!endFoldBlockFound && !(lineLookLevel & SC_FOLDLEVELWHITEFLAG) && lineLookLevelNumber < levelNumber) {
+ endFoldBlockFound = true;
+ endFoldBlock = lineLook - 1;
+ if (!endMarginCorrectlyDrawnZoneFound) {
+ endMarginCorrectlyDrawnZoneFound = true;
+ endMarginCorrectlyDrawnZone = lineLook;
+ }
+ } else if (!endFoldBlockFound && lineLookLevel == SC_FOLDLEVELBASE) {
+ endFoldBlockFound = true;
+ endFoldBlock = -1;
+ }
+ if (!endMarginCorrectlyDrawnZoneFound && (lineLookLevel & SC_FOLDLEVELHEADERFLAG) &&
+ //Managed the folding block when a fold header does not have any subordinate lines to fold away.
+ (levelNumber < (GetLevel(lineLook + 1) & SC_FOLDLEVELNUMBERMASK))) {
+ endMarginCorrectlyDrawnZoneFound = true;
+ endMarginCorrectlyDrawnZone = lineLook;
+ }
+ }
+ if (!endFoldBlockFound && ((lineLook > endLine && lineLookLevelNumber < levelNumber) ||
+ (levelNumber > SC_FOLDLEVELBASE))) {
+ //manage when endfold is incorrect or on last line.
+ endFoldBlock = lineLook - 1;
+ //useless to set endMarginCorrectlyDrawnZone.
+ //if endMarginCorrectlyDrawnZoneFound equals false then endMarginCorrectlyDrawnZone already equals to endLine + 1.
+ }
+
+ highlightDelimiter.beginFoldBlock = beginFoldBlock;
+ highlightDelimiter.endFoldBlock = endFoldBlock;
+ highlightDelimiter.beginMarginCorrectlyDrawnZone = beginMarginCorrectlyDrawnZone;
+ highlightDelimiter.endMarginCorrectlyDrawnZone = endMarginCorrectlyDrawnZone;
+}
+
int Document::ClampPositionIntoDocument(int pos) {
return Platform::Clamp(pos, 0, Length());
}
@@ -312,8 +471,6 @@ bool Document::IsCrLf(int pos) {
return (cb.CharAt(pos) == '\r') && (cb.CharAt(pos + 1) == '\n');
}
-static const int maxBytesInDBCSCharacter=5;
-
int Document::LenChar(int pos) {
if (pos < 0) {
return 1;
@@ -334,13 +491,7 @@ int Document::LenChar(int pos) {
else
return len;
} else if (dbcsCodePage) {
- char mbstr[maxBytesInDBCSCharacter+1];
- int i;
- for (i=0; i<Platform::DBCSCharMaxLength(); i++) {
- mbstr[i] = cb.CharAt(pos+i);
- }
- mbstr[i] = '\0';
- return Platform::DBCSCharLength(dbcsCodePage, mbstr);
+ return IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1;
} else {
return 1;
}
@@ -364,7 +515,7 @@ static int BytesFromLead(int leadByte) {
return 0;
}
-bool Document::InGoodUTF8(int pos, int &start, int &end) {
+bool Document::InGoodUTF8(int pos, int &start, int &end) const {
int lead = pos;
while ((lead>0) && (pos-lead < 4) && IsTrailByte(static_cast<unsigned char>(cb.CharAt(lead-1))))
lead--;
@@ -416,8 +567,6 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
return pos - 1;
}
- // Not between CR and LF
-
if (dbcsCodePage) {
if (SC_CP_UTF8 == dbcsCodePage) {
unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
@@ -433,16 +582,18 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
} else {
// Anchor DBCS calculations at start of line because start of line can
// not be a DBCS trail byte.
- int posCheck = LineStart(LineFromPosition(pos));
- while (posCheck < pos) {
- char mbstr[maxBytesInDBCSCharacter+1];
- int i;
- for(i=0;i<Platform::DBCSCharMaxLength();i++) {
- mbstr[i] = cb.CharAt(posCheck+i);
- }
- mbstr[i] = '\0';
+ int posStartLine = LineStart(LineFromPosition(pos));
+ if (pos == posStartLine)
+ return pos;
+
+ // Step back until a non-lead-byte is found.
+ int posCheck = pos;
+ while ((posCheck > posStartLine) && IsDBCSLeadByte(cb.CharAt(posCheck-1)))
+ posCheck--;
- int mbsize = Platform::DBCSCharLength(dbcsCodePage, mbstr);
+ // Check from known start of character.
+ while (posCheck < pos) {
+ int mbsize = IsDBCSLeadByte(cb.CharAt(posCheck)) ? 2 : 1;
if (posCheck + mbsize == pos) {
return pos;
} else if (posCheck + mbsize > pos) {
@@ -460,6 +611,157 @@ int Document::MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd) {
return pos;
}
+// NextPosition moves between valid positions - it can not handle a position in the middle of a
+// multi-byte character. It is used to iterate through text more efficiently than MovePositionOutsideChar.
+// A \r\n pair is treated as two characters.
+int Document::NextPosition(int pos, int moveDir) const {
+ // If out of range, just return minimum/maximum value.
+ int increment = (moveDir > 0) ? 1 : -1;
+ if (pos + increment <= 0)
+ return 0;
+ if (pos + increment >= Length())
+ return Length();
+
+ if (dbcsCodePage) {
+ if (SC_CP_UTF8 == dbcsCodePage) {
+ pos += increment;
+ unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
+ int startUTF = pos;
+ int endUTF = pos;
+ if (IsTrailByte(ch) && InGoodUTF8(pos, startUTF, endUTF)) {
+ // ch is a trail byte within a UTF-8 character
+ if (moveDir > 0)
+ pos = endUTF;
+ else
+ pos = startUTF;
+ }
+ } else {
+ if (moveDir > 0) {
+ int mbsize = IsDBCSLeadByte(cb.CharAt(pos)) ? 2 : 1;
+ pos += mbsize;
+ if (pos > Length())
+ pos = Length();
+ } else {
+ // Anchor DBCS calculations at start of line because start of line can
+ // not be a DBCS trail byte.
+ int posStartLine = LineStart(LineFromPosition(pos));
+ // See http://msdn.microsoft.com/en-us/library/cc194792%28v=MSDN.10%29.aspx
+ // http://msdn.microsoft.com/en-us/library/cc194790.aspx
+ if ((pos - 1) <= posStartLine) {
+ return pos - 1;
+ } else if (IsDBCSLeadByte(cb.CharAt(pos - 1))) {
+ // Must actually be trail byte
+ return pos - 2;
+ } else {
+ // Otherwise, step back until a non-lead-byte is found.
+ int posTemp = pos - 1;
+ while (posStartLine <= --posTemp && IsDBCSLeadByte(cb.CharAt(posTemp)))
+ ;
+ // Now posTemp+1 must point to the beginning of a character,
+ // so figure out whether we went back an even or an odd
+ // number of bytes and go back 1 or 2 bytes, respectively.
+ return (pos - 1 - ((pos - posTemp) & 1));
+ }
+ }
+ }
+ } else {
+ pos += increment;
+ }
+
+ return pos;
+}
+
+bool Document::NextCharacter(int &pos, int moveDir) {
+ // Returns true if pos changed
+ int posNext = NextPosition(pos, moveDir);
+ if (posNext == pos) {
+ return false;
+ } else {
+ pos = posNext;
+ return true;
+ }
+}
+
+int SCI_METHOD Document::CodePage() const {
+ return dbcsCodePage;
+}
+
+bool SCI_METHOD Document::IsDBCSLeadByte(char ch) const {
+ // Byte ranges found in Wikipedia articles with relevant search strings in each case
+ unsigned char uch = static_cast<unsigned char>(ch);
+ switch (dbcsCodePage) {
+ case 932:
+ // Shift_jis
+ return ((uch >= 0x81) && (uch <= 0x9F)) ||
+ ((uch >= 0xE0) && (uch <= 0xEF));
+ case 936:
+ // GBK
+ return (uch >= 0x81) && (uch <= 0xFE);
+ case 949:
+ // Korean Wansung KS C-5601-1987
+ return (uch >= 0x81) && (uch <= 0xFE);
+ case 950:
+ // Big5
+ return (uch >= 0x81) && (uch <= 0xFE);
+ case 1361:
+ // Korean Johab KS C-5601-1992
+ return
+ ((uch >= 0x84) && (uch <= 0xD3)) ||
+ ((uch >= 0xD8) && (uch <= 0xDE)) ||
+ ((uch >= 0xE0) && (uch <= 0xF9));
+ }
+ return false;
+}
+
+inline bool IsSpaceOrTab(int ch) {
+ return ch == ' ' || ch == '\t';
+}
+
+// Need to break text into segments near lengthSegment but taking into
+// account the encoding to not break inside a UTF-8 or DBCS character
+// and also trying to avoid breaking inside a pair of combining characters.
+// The segment length must always be long enough (more than 4 bytes)
+// so that there will be at least one whole character to make a segment.
+// For UTF-8, text must consist only of valid whole characters.
+// In preference order from best to worst:
+// 1) Break after space
+// 2) Break before punctuation
+// 3) Break after whole character
+
+int Document::SafeSegment(const char *text, int length, int lengthSegment) {
+ if (length <= lengthSegment)
+ return length;
+ int lastSpaceBreak = -1;
+ int lastPunctuationBreak = -1;
+ int lastEncodingAllowedBreak = -1;
+ for (int j=0; j < lengthSegment;) {
+ unsigned char ch = static_cast<unsigned char>(text[j]);
+ if (j > 0) {
+ if (IsSpaceOrTab(text[j - 1]) && !IsSpaceOrTab(text[j])) {
+ lastSpaceBreak = j;
+ }
+ if (ch < 'A') {
+ lastPunctuationBreak = j;
+ }
+ }
+ lastEncodingAllowedBreak = j;
+
+ if (dbcsCodePage == SC_CP_UTF8) {
+ j += (ch < 0x80) ? 1 : BytesFromLead(ch);
+ } else if (dbcsCodePage) {
+ j += IsDBCSLeadByte(ch) ? 2 : 1;
+ } else {
+ j++;
+ }
+ }
+ if (lastSpaceBreak >= 0) {
+ return lastSpaceBreak;
+ } else if (lastPunctuationBreak >= 0) {
+ return lastPunctuationBreak;
+ }
+ return lastEncodingAllowedBreak;
+}
+
void Document::ModifiedAt(int pos) {
if (endStyled > pos)
endStyled = pos;
@@ -702,7 +1004,7 @@ void Document::DelCharBack(int pos) {
} else if (IsCrLf(pos - 2)) {
DeleteChars(pos - 2, 2);
} else if (dbcsCodePage) {
- int startChar = MovePositionOutsideChar(pos - 1, -1, false);
+ int startChar = NextPosition(pos, -1);
DeleteChars(startChar, pos - startChar);
} else {
DeleteChars(pos - 1, 1);
@@ -734,12 +1036,12 @@ static void CreateIndentation(char *linebuf, int length, int indent, int tabSize
*linebuf = '\0';
}
-int Document::GetLineIndentation(int line) {
+int SCI_METHOD Document::GetLineIndentation(int line) {
int indent = 0;
if ((line >= 0) && (line < LinesTotal())) {
int lineStart = LineStart(line);
int length = Length();
- for (int i = lineStart;i < length;i++) {
+ for (int i = lineStart; i < length; i++) {
char ch = cb.CharAt(i);
if (ch == ' ')
indent++;
@@ -782,7 +1084,7 @@ int Document::GetColumn(int pos) {
int column = 0;
int line = LineFromPosition(pos);
if ((line >= 0) && (line < LinesTotal())) {
- for (int i = LineStart(line);i < pos;) {
+ for (int i = LineStart(line); i < pos;) {
char ch = cb.CharAt(i);
if (ch == '\t') {
column = NextTab(column, tabInChars);
@@ -795,7 +1097,7 @@ int Document::GetColumn(int pos) {
return column;
} else {
column++;
- i = MovePositionOutsideChar(i + 1, 1, false);
+ i = NextPosition(i, 1);
}
}
}
@@ -817,7 +1119,7 @@ int Document::FindColumn(int line, int column) {
return position;
} else {
columnCurrent++;
- position = MovePositionOutsideChar(position + 1, 1, false);
+ position = NextPosition(position, 1);
}
}
}
@@ -969,7 +1271,7 @@ int Document::ExtendWordSelect(int pos, int delta, bool onlyWordCharacters) {
while (pos < (Length()) && (WordCharClass(cb.CharAt(pos)) == ccStart))
pos++;
}
- return MovePositionOutsideChar(pos, delta);
+ return MovePositionOutsideChar(pos, delta, true);
}
/**
@@ -1074,79 +1376,199 @@ static inline char MakeLowerCase(char ch) {
return static_cast<char>(ch - 'A' + 'a');
}
+static bool GoodTrailByte(int v) {
+ return (v >= 0x80) && (v < 0xc0);
+}
+
+size_t Document::ExtractChar(int pos, char *bytes) {
+ unsigned char ch = static_cast<unsigned char>(cb.CharAt(pos));
+ size_t widthChar = UTF8CharLength(ch);
+ bytes[0] = ch;
+ for (size_t i=1; i<widthChar; i++) {
+ bytes[i] = cb.CharAt(pos+i);
+ if (!GoodTrailByte(static_cast<unsigned char>(bytes[i]))) { // Bad byte
+ widthChar = 1;
+ }
+ }
+ return widthChar;
+}
+
+CaseFolderTable::CaseFolderTable() {
+ for (size_t iChar=0; iChar<sizeof(mapping); iChar++) {
+ mapping[iChar] = static_cast<char>(iChar);
+ }
+}
+
+CaseFolderTable::~CaseFolderTable() {
+}
+
+size_t CaseFolderTable::Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
+ if (lenMixed > sizeFolded) {
+ return 0;
+ } else {
+ for (size_t i=0; i<lenMixed; i++) {
+ folded[i] = mapping[static_cast<unsigned char>(mixed[i])];
+ }
+ return lenMixed;
+ }
+}
+
+void CaseFolderTable::SetTranslation(char ch, char chTranslation) {
+ mapping[static_cast<unsigned char>(ch)] = chTranslation;
+}
+
+void CaseFolderTable::StandardASCII() {
+ for (size_t iChar=0; iChar<sizeof(mapping); iChar++) {
+ if (iChar >= 'A' && iChar <= 'Z') {
+ mapping[iChar] = static_cast<char>(iChar - 'A' + 'a');
+ } else {
+ mapping[iChar] = static_cast<char>(iChar);
+ }
+ }
+}
+
+bool Document::MatchesWordOptions(bool word, bool wordStart, int pos, int length) {
+ return (!word && !wordStart) ||
+ (word && IsWordAt(pos, pos + length)) ||
+ (wordStart && IsWordStartAt(pos));
+}
+
/**
* Find text in document, supporting both forward and backward
* searches (just pass minPos > maxPos to do a backward search)
* Has not been tested with backwards DBCS searches yet.
*/
-long Document::FindText(int minPos, int maxPos, const char *s,
+long Document::FindText(int minPos, int maxPos, const char *search,
bool caseSensitive, bool word, bool wordStart, bool regExp, int flags,
- int *length) {
+ int *length, CaseFolder *pcf) {
+ if (*length <= 0)
+ return minPos;
if (regExp) {
if (!regex)
regex = CreateRegexSearch(&charClass);
- return regex->FindText(this, minPos, maxPos, s, caseSensitive, word, wordStart, flags, length);
+ return regex->FindText(this, minPos, maxPos, search, caseSensitive, word, wordStart, flags, length);
} else {
- bool forward = minPos <= maxPos;
- int increment = forward ? 1 : -1;
+ const bool forward = minPos <= maxPos;
+ const int increment = forward ? 1 : -1;
// Range endpoints should not be inside DBCS characters, but just in case, move them.
- int startPos = MovePositionOutsideChar(minPos, increment, false);
- int endPos = MovePositionOutsideChar(maxPos, increment, false);
+ const int startPos = MovePositionOutsideChar(minPos, increment, false);
+ const int endPos = MovePositionOutsideChar(maxPos, increment, false);
// Compute actual search ranges needed
- int lengthFind = *length;
- if (lengthFind == -1)
- lengthFind = static_cast<int>(strlen(s));
- int endSearch = endPos;
- if (startPos <= endPos) {
- endSearch = endPos - lengthFind + 1;
- }
+ const int lengthFind = (*length == -1) ? static_cast<int>(strlen(search)) : *length;
+ const int endSearch = (startPos <= endPos) ? endPos - lengthFind + 1 : endPos;
+
//Platform::DebugPrintf("Find %d %d %s %d\n", startPos, endPos, ft->lpstrText, lengthFind);
- char firstChar = s[0];
- if (!caseSensitive)
- firstChar = static_cast<char>(MakeUpperCase(firstChar));
- int pos = forward ? startPos : (startPos - 1);
- while (forward ? (pos < endSearch) : (pos >= endSearch)) {
- char ch = CharAt(pos);
- if (caseSensitive) {
- if (ch == firstChar) {
- bool found = true;
- if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
- for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
- ch = CharAt(pos + posMatch);
- if (ch != s[posMatch])
- found = false;
- }
- if (found) {
- if ((!word && !wordStart) ||
- (word && IsWordAt(pos, pos + lengthFind)) ||
- (wordStart && IsWordStartAt(pos)))
- return pos;
- }
+ const int limitPos = Platform::Maximum(startPos, endPos);
+ int pos = startPos;
+ if (!forward) {
+ // Back all of a character
+ pos = NextPosition(pos, increment);
+ }
+ if (caseSensitive) {
+ while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+ bool found = (pos + lengthFind) <= limitPos;
+ for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) {
+ found = CharAt(pos + indexSearch) == search[indexSearch];
}
- } else {
- if (MakeUpperCase(ch) == firstChar) {
- bool found = true;
- if (pos + lengthFind > Platform::Maximum(startPos, endPos)) found = false;
- for (int posMatch = 1; posMatch < lengthFind && found; posMatch++) {
- ch = CharAt(pos + posMatch);
- if (MakeUpperCase(ch) != MakeUpperCase(s[posMatch]))
- found = false;
+ if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
+ return pos;
+ }
+ if (!NextCharacter(pos, increment))
+ break;
+ }
+ } else if (SC_CP_UTF8 == dbcsCodePage) {
+ const size_t maxBytesCharacter = 4;
+ const size_t maxFoldingExpansion = 4;
+ std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
+ const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
+ while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+ int widthFirstCharacter = 0;
+ int indexDocument = 0;
+ int indexSearch = 0;
+ bool characterMatches = true;
+ while (characterMatches &&
+ ((pos + indexDocument) < limitPos) &&
+ (indexSearch < lenSearch)) {
+ char bytes[maxBytesCharacter + 1];
+ bytes[maxBytesCharacter] = 0;
+ const int widthChar = ExtractChar(pos + indexDocument, bytes);
+ if (!widthFirstCharacter)
+ widthFirstCharacter = widthChar;
+ char folded[maxBytesCharacter * maxFoldingExpansion + 1];
+ const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
+ folded[lenFlat] = 0;
+ // Does folded match the buffer
+ characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
+ indexDocument += widthChar;
+ indexSearch += lenFlat;
+ }
+ if (characterMatches && (indexSearch == static_cast<int>(lenSearch))) {
+ if (MatchesWordOptions(word, wordStart, pos, indexDocument)) {
+ *length = indexDocument;
+ return pos;
}
- if (found) {
- if ((!word && !wordStart) ||
- (word && IsWordAt(pos, pos + lengthFind)) ||
- (wordStart && IsWordStartAt(pos)))
- return pos;
+ }
+ if (forward) {
+ pos += widthFirstCharacter;
+ } else {
+ if (!NextCharacter(pos, increment))
+ break;
+ }
+ }
+ } else if (dbcsCodePage) {
+ const size_t maxBytesCharacter = 2;
+ const size_t maxFoldingExpansion = 4;
+ std::vector<char> searchThing(lengthFind * maxBytesCharacter * maxFoldingExpansion + 1);
+ const int lenSearch = pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
+ while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+ int indexDocument = 0;
+ int indexSearch = 0;
+ bool characterMatches = true;
+ while (characterMatches &&
+ ((pos + indexDocument) < limitPos) &&
+ (indexSearch < lenSearch)) {
+ char bytes[maxBytesCharacter + 1];
+ bytes[0] = cb.CharAt(pos + indexDocument);
+ const int widthChar = IsDBCSLeadByte(bytes[0]) ? 2 : 1;
+ if (widthChar == 2)
+ bytes[1] = cb.CharAt(pos + indexDocument + 1);
+ char folded[maxBytesCharacter * maxFoldingExpansion + 1];
+ const int lenFlat = pcf->Fold(folded, sizeof(folded), bytes, widthChar);
+ folded[lenFlat] = 0;
+ // Does folded match the buffer
+ characterMatches = 0 == memcmp(folded, &searchThing[0] + indexSearch, lenFlat);
+ indexDocument += widthChar;
+ indexSearch += lenFlat;
+ }
+ if (characterMatches && (indexSearch == static_cast<int>(lenSearch))) {
+ if (MatchesWordOptions(word, wordStart, pos, indexDocument)) {
+ *length = indexDocument;
+ return pos;
}
}
+ if (!NextCharacter(pos, increment))
+ break;
}
- pos += increment;
- if (dbcsCodePage && (pos >= 0)) {
- // Ensure trying to match from start of character
- pos = MovePositionOutsideChar(pos, increment, false);
+ } else {
+ CaseFolderTable caseFolder;
+ std::vector<char> searchThing(lengthFind + 1);
+ pcf->Fold(&searchThing[0], searchThing.size(), search, lengthFind);
+ while (forward ? (pos < endSearch) : (pos >= endSearch)) {
+ bool found = (pos + lengthFind) <= limitPos;
+ for (int indexSearch = 0; (indexSearch < lengthFind) && found; indexSearch++) {
+ char ch = CharAt(pos + indexSearch);
+ char folded[2];
+ pcf->Fold(folded, sizeof(folded), &ch, 1);
+ found = folded[0] == searchThing[indexSearch];
+ }
+ if (found && MatchesWordOptions(word, wordStart, pos, lengthFind)) {
+ return pos;
+ }
+ if (!NextCharacter(pos, increment))
+ break;
}
}
}
@@ -1155,7 +1577,10 @@ long Document::FindText(int minPos, int maxPos, const char *s,
}
const char *Document::SubstituteByPosition(const char *text, int *length) {
- return regex->SubstituteByPosition(this, text, length);
+ if (regex)
+ return regex->SubstituteByPosition(this, text, length);
+ else
+ return 0;
}
int Document::LinesTotal() const {
@@ -1194,12 +1619,12 @@ void Document::SetStylingBits(int bits) {
stylingBitsMask = (1 << stylingBits) - 1;
}
-void Document::StartStyling(int position, char mask) {
+void SCI_METHOD Document::StartStyling(int position, char mask) {
stylingMask = mask;
endStyled = position;
}
-bool Document::SetStyleFor(int length, char style) {
+bool SCI_METHOD Document::SetStyleFor(int length, char style) {
if (enteredStyling != 0) {
return false;
} else {
@@ -1217,7 +1642,7 @@ bool Document::SetStyleFor(int length, char style) {
}
}
-bool Document::SetStyles(int length, const char *styles) {
+bool SCI_METHOD Document::SetStyles(int length, const char *styles) {
if (enteredStyling != 0) {
return false;
} else {
@@ -1248,75 +1673,93 @@ bool Document::SetStyles(int length, const char *styles) {
void Document::EnsureStyledTo(int pos) {
if ((enteredStyling == 0) && (pos > GetEndStyled())) {
IncrementStyleClock();
- // Ask the watchers to style, and stop as soon as one responds.
- for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
- watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos);
+ if (pli && !pli->UseContainerLexing()) {
+ int lineEndStyled = LineFromPosition(GetEndStyled());
+ int endStyledTo = LineStart(lineEndStyled);
+ pli->Colourise(endStyledTo, pos);
+ } else {
+ // Ask the watchers to style, and stop as soon as one responds.
+ for (int i = 0; pos > GetEndStyled() && i < lenWatchers; i++) {
+ watchers[i].watcher->NotifyStyleNeeded(this, watchers[i].userData, pos);
+ }
}
}
}
-int Document::SetLineState(int line, int state) {
- int statePrevious = static_cast<LineState*>(perLineData[ldState])->SetLineState(line, state);
+void Document::LexerChanged() {
+ // Tell the watchers the lexer has changed.
+ for (int i = 0; i < lenWatchers; i++) {
+ watchers[i].watcher->NotifyLexerChanged(this, watchers[i].userData);
+ }
+}
+
+int SCI_METHOD Document::SetLineState(int line, int state) {
+ int statePrevious = static_cast<LineState *>(perLineData[ldState])->SetLineState(line, state);
if (state != statePrevious) {
- DocModification mh(SC_MOD_CHANGELINESTATE, 0, 0, 0, 0, line);
+ DocModification mh(SC_MOD_CHANGELINESTATE, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
}
return statePrevious;
}
-int Document::GetLineState(int line) {
- return static_cast<LineState*>(perLineData[ldState])->GetLineState(line);
+int SCI_METHOD Document::GetLineState(int line) const {
+ return static_cast<LineState *>(perLineData[ldState])->GetLineState(line);
}
-int Document::GetMaxLineState() {
- return static_cast<LineState*>(perLineData[ldState])->GetMaxLineState();
+int Document::GetMaxLineState() {
+ return static_cast<LineState *>(perLineData[ldState])->GetMaxLineState();
+}
+
+void SCI_METHOD Document::ChangeLexerState(int start, int end) {
+ DocModification mh(SC_MOD_LEXERSTATE, start, end-start, 0, 0, 0);
+ NotifyModified(mh);
}
StyledText Document::MarginStyledText(int line) {
- LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldMargin]);
- return StyledText(pla->Length(line), pla->Text(line),
+ LineAnnotation *pla = static_cast<LineAnnotation *>(perLineData[ldMargin]);
+ return StyledText(pla->Length(line), pla->Text(line),
pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
}
void Document::MarginSetText(int line, const char *text) {
- static_cast<LineAnnotation*>(perLineData[ldMargin])->SetText(line, text);
+ static_cast<LineAnnotation *>(perLineData[ldMargin])->SetText(line, text);
DocModification mh(SC_MOD_CHANGEMARGIN, LineStart(line), 0, 0, 0, line);
NotifyModified(mh);
}
void Document::MarginSetStyle(int line, int style) {
- static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyle(line, style);
+ static_cast<LineAnnotation *>(perLineData[ldMargin])->SetStyle(line, style);
}
void Document::MarginSetStyles(int line, const unsigned char *styles) {
- static_cast<LineAnnotation*>(perLineData[ldMargin])->SetStyles(line, styles);
+ static_cast<LineAnnotation *>(perLineData[ldMargin])->SetStyles(line, styles);
}
int Document::MarginLength(int line) const {
- return static_cast<LineAnnotation*>(perLineData[ldMargin])->Length(line);
+ return static_cast<LineAnnotation *>(perLineData[ldMargin])->Length(line);
}
void Document::MarginClearAll() {
int maxEditorLine = LinesTotal();
- for (int l=0;l<maxEditorLine;l++)
+ for (int l=0; l<maxEditorLine; l++)
MarginSetText(l, 0);
// Free remaining data
- static_cast<LineAnnotation*>(perLineData[ldMargin])->ClearAll();
+ static_cast<LineAnnotation *>(perLineData[ldMargin])->ClearAll();
}
bool Document::AnnotationAny() const {
- return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->AnySet();
+ return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->AnySet();
}
StyledText Document::AnnotationStyledText(int line) {
- LineAnnotation *pla = static_cast<LineAnnotation*>(perLineData[ldAnnotation]);
- return StyledText(pla->Length(line), pla->Text(line),
+ LineAnnotation *pla = static_cast<LineAnnotation *>(perLineData[ldAnnotation]);
+ return StyledText(pla->Length(line), pla->Text(line),
pla->MultipleStyles(line), pla->Style(line), pla->Styles(line));
}
void Document::AnnotationSetText(int line, const char *text) {
const int linesBefore = AnnotationLines(line);
- static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetText(line, text);
+ static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetText(line, text);
const int linesAfter = AnnotationLines(line);
DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line);
mh.annotationLinesAdded = linesAfter - linesBefore;
@@ -1324,34 +1767,36 @@ void Document::AnnotationSetText(int line, const char *text) {
}
void Document::AnnotationSetStyle(int line, int style) {
- static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyle(line, style);
+ static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetStyle(line, style);
+ DocModification mh(SC_MOD_CHANGEANNOTATION, LineStart(line), 0, 0, 0, line);
+ NotifyModified(mh);
}
void Document::AnnotationSetStyles(int line, const unsigned char *styles) {
- static_cast<LineAnnotation*>(perLineData[ldAnnotation])->SetStyles(line, styles);
+ static_cast<LineAnnotation *>(perLineData[ldAnnotation])->SetStyles(line, styles);
}
int Document::AnnotationLength(int line) const {
- return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Length(line);
+ return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->Length(line);
}
int Document::AnnotationLines(int line) const {
- return static_cast<LineAnnotation*>(perLineData[ldAnnotation])->Lines(line);
+ return static_cast<LineAnnotation *>(perLineData[ldAnnotation])->Lines(line);
}
void Document::AnnotationClearAll() {
int maxEditorLine = LinesTotal();
- for (int l=0;l<maxEditorLine;l++)
+ for (int l=0; l<maxEditorLine; l++)
AnnotationSetText(l, 0);
// Free remaining data
- static_cast<LineAnnotation*>(perLineData[ldAnnotation])->ClearAll();
+ static_cast<LineAnnotation *>(perLineData[ldAnnotation])->ClearAll();
}
void Document::IncrementStyleClock() {
styleClock = (styleClock + 1) % 0x100000;
}
-void Document::DecorationFillRange(int position, int value, int fillLength) {
+void SCI_METHOD Document::DecorationFillRange(int position, int value, int fillLength) {
if (decorations.FillRange(position, value, fillLength)) {
DocModification mh(SC_MOD_CHANGEINDICATOR | SC_PERFORMED_USER,
position, fillLength);
@@ -1523,11 +1968,11 @@ bool IsLineEndChar(char c) {
int Document::ExtendStyleRange(int pos, int delta, bool singleLine) {
int sStart = cb.StyleAt(pos);
if (delta < 0) {
- while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))) )
+ while (pos > 0 && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))))
pos--;
pos++;
} else {
- while (pos < (Length()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))) )
+ while (pos < (Length()) && (cb.StyleAt(pos) == sStart) && (!singleLine || !IsLineEndChar(cb.CharAt(pos))))
pos++;
}
return pos;
@@ -1567,9 +2012,8 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) {
if (chBrace == '(' || chBrace == '[' || chBrace == '{' || chBrace == '<')
direction = 1;
int depth = 1;
- position = position + direction;
+ position = NextPosition(position, direction);
while ((position >= 0) && (position < Length())) {
- position = MovePositionOutsideChar(position, direction);
char chAtPos = CharAt(position);
char styAtPos = static_cast<char>(StyleAt(position) & stylingBitsMask);
if ((position > GetEndStyled()) || (styAtPos == styBrace)) {
@@ -1580,7 +2024,10 @@ int Document::BraceMatch(int position, int /*maxReStyle*/) {
if (depth == 0)
return position;
}
- position = position + direction;
+ int positionBeforeMove = position;
+ position = NextPosition(position, direction);
+ if (position == positionBeforeMove)
+ break;
}
return - 1;
}
@@ -1600,7 +2047,7 @@ public:
bool caseSensitive, bool word, bool wordStart, int flags,
int *length);
- virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length);
+ virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length);
private:
RESearch search;
@@ -1656,6 +2103,12 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
// the start position is at end of line or between line end characters.
lineRangeStart++;
startPos = doc->LineStart(lineRangeStart);
+ } else if ((increment == -1) &&
+ (startPos <= doc->LineStart(lineRangeStart)) &&
+ (lineRangeStart > lineRangeEnd)) {
+ // the start position is at beginning of line.
+ lineRangeStart--;
+ startPos = doc->LineEnd(lineRangeStart);
}
int pos = -1;
int lenRet = 0;
@@ -1693,7 +2146,8 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
if (success) {
pos = search.bopat[0];
lenRet = search.eopat[0] - search.bopat[0];
- if (increment == -1) {
+ // There can be only one start of a line, so no need to look for last match in line
+ if ((increment == -1) && (s[0] != '^')) {
// Check for the last match on this line.
int repetitions = 1000; // Break out of infinite loop
while (success && (search.eopat[0] <= endOfLine) && (repetitions--)) {
@@ -1715,7 +2169,7 @@ long BuiltinRegex::FindText(Document *doc, int minPos, int maxPos, const char *s
return pos;
}
-const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text, int *length) {
+const char *BuiltinRegex::SubstituteByPosition(Document *doc, const char *text, int *length) {
delete []substituted;
substituted = 0;
DocumentIndexer di(doc, doc->Length());
@@ -1737,6 +2191,7 @@ const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text,
case 'r':
case 't':
case 'v':
+ case '\\':
i++;
}
lenResult++;
@@ -1780,6 +2235,9 @@ const char *BuiltinRegex::SubstituteByPosition(Document* doc, const char *text,
case 'v':
*o++ = '\v';
break;
+ case '\\':
+ *o++ = '\\';
+ break;
default:
*o++ = '\\';
j--;
diff --git a/plugins/scintilla/scintilla/Document.h b/plugins/scintilla/scintilla/Document.h
index 240d59e..7858db7 100644
--- a/plugins/scintilla/scintilla/Document.h
+++ b/plugins/scintilla/scintilla/Document.h
@@ -2,7 +2,7 @@
/** @file Document.h
** Text document that handles notifications, DBCS, styling, words and end of line.
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef DOCUMENT_H
@@ -32,10 +32,10 @@ public:
Range(Position pos=0) :
start(pos), end(pos) {
- };
+ }
Range(Position start_, Position end_) :
start(start_), end(end_) {
- };
+ }
bool Valid() const {
return (start != invalidPosition) && (end != invalidPosition);
@@ -81,17 +81,17 @@ class Document;
*/
class RegexSearchBase {
public:
- virtual ~RegexSearchBase(){}
+ virtual ~RegexSearchBase() {}
- virtual long FindText(Document* doc, int minPos, int maxPos, const char *s,
+ virtual long FindText(Document *doc, int minPos, int maxPos, const char *s,
bool caseSensitive, bool word, bool wordStart, int flags, int *length) = 0;
///@return String with the substitutions, must remain valid until the next call or destruction
- virtual const char *SubstituteByPosition(Document* doc, const char *text, int *length) = 0;
+ virtual const char *SubstituteByPosition(Document *doc, const char *text, int *length) = 0;
};
/// Factory function for RegexSearchBase
-extern RegexSearchBase* CreateRegexSearch(CharClassify *charClassTable);
+extern RegexSearchBase *CreateRegexSearch(CharClassify *charClassTable);
struct StyledText {
size_t length;
@@ -99,7 +99,7 @@ struct StyledText {
bool multipleStyles;
size_t style;
const unsigned char *styles;
- StyledText( size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) :
+ StyledText(size_t length_, const char *text_, bool multipleStyles_, int style_, const unsigned char *styles_) :
length(length_), text(text_), multipleStyles(multipleStyles_), style(style_), styles(styles_) {
}
// Return number of bytes from start to before '\n' or end of text.
@@ -115,9 +115,86 @@ struct StyledText {
}
};
+class HighlightDelimiter {
+public:
+ HighlightDelimiter() {
+ beginFoldBlock = -1;
+ endFoldBlock = -1;
+ beginMarginCorrectlyDrawnZone = -1;
+ endMarginCorrectlyDrawnZone = -1;
+ isEnabled = false;
+ }
+
+ bool NeedsDrawing(int line) {
+ return isEnabled && (line <= beginMarginCorrectlyDrawnZone || endMarginCorrectlyDrawnZone <= line);
+ }
+
+ bool isCurrentBlockHighlight(int line) {
+ return isEnabled && beginFoldBlock != -1 && beginFoldBlock <= line && line <= endFoldBlock;
+ }
+
+ bool isHeadBlockFold(int line) {
+ return beginFoldBlock == line && line < endFoldBlock;
+ }
+
+ bool isBodyBlockFold(int line) {
+ return beginFoldBlock != -1 && beginFoldBlock < line && line < endFoldBlock;
+ }
+
+ bool isTailBlockFold(int line) {
+ return beginFoldBlock != -1 && beginFoldBlock < line && line == endFoldBlock;
+ }
+
+ // beginFoldBlock : Begin of current fold block.
+ // endStartBlock : End of current fold block.
+ // beginMarginCorrectlyDrawnZone : Begin of zone where margin is correctly drawn.
+ // endMarginCorrectlyDrawnZone : End of zone where margin is correctly drawn.
+ int beginFoldBlock;
+ int endFoldBlock;
+ int beginMarginCorrectlyDrawnZone;
+ int endMarginCorrectlyDrawnZone;
+ bool isEnabled;
+};
+
+class CaseFolder {
+public:
+ virtual ~CaseFolder() {
+ }
+ virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) = 0;
+};
+
+class CaseFolderTable : public CaseFolder {
+protected:
+ char mapping[256];
+public:
+ CaseFolderTable();
+ virtual ~CaseFolderTable();
+ virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed);
+ void SetTranslation(char ch, char chTranslation);
+ void StandardASCII();
+};
+
+class Document;
+
+class LexInterface {
+protected:
+ Document *pdoc;
+ ILexer *instance;
+ bool performingStyle; ///< Prevent reentrance
+public:
+ LexInterface(Document *pdoc_) : pdoc(pdoc_), instance(0), performingStyle(false) {
+ }
+ virtual ~LexInterface() {
+ }
+ void Colourise(int start, int end);
+ bool UseContainerLexing() const {
+ return instance == 0;
+ }
+};
+
/**
*/
-class Document : PerLine {
+class Document : PerLine, public IDocument {
public:
/** Used to pair watcher pointer with user data. */
@@ -147,13 +224,16 @@ private:
int lenWatchers;
// ldSize is not real data - it is for dimensions and loops
- enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize };
+ enum lineData { ldMarkers, ldLevels, ldState, ldMargin, ldAnnotation, ldSize };
PerLine *perLineData[ldSize];
bool matchesValid;
- RegexSearchBase* regex;
+ RegexSearchBase *regex;
public:
+
+ LexInterface *pli;
+
int stylingBits;
int stylingBitsMask;
@@ -179,12 +259,23 @@ public:
virtual void InsertLine(int line);
virtual void RemoveLine(int line);
- int LineFromPosition(int pos) const;
+ int SCI_METHOD Version() const {
+ return dvOriginal;
+ }
+
+ void SCI_METHOD SetErrorStatus(int status);
+
+ int SCI_METHOD LineFromPosition(int pos) const;
int ClampPositionIntoDocument(int pos);
bool IsCrLf(int pos);
int LenChar(int pos);
- bool InGoodUTF8(int pos, int &start, int &end);
+ bool InGoodUTF8(int pos, int &start, int &end) const;
int MovePositionOutsideChar(int pos, int moveDir, bool checkLineEnd=true);
+ int NextPosition(int pos, int moveDir) const;
+ bool NextCharacter(int &pos, int moveDir); // Returns true if pos changed
+ int SCI_METHOD CodePage() const;
+ bool SCI_METHOD IsDBCSLeadByte(char ch) const;
+ int SafeSegment(const char *text, int length, int lengthSegment);
// Gateways to modifying document
void ModifiedAt(int pos);
@@ -205,9 +296,9 @@ public:
void AddUndoAction(int token, bool mayCoalesce) { cb.AddUndoAction(token, mayCoalesce); }
void SetSavePoint();
bool IsSavePoint() { return cb.IsSavePoint(); }
- const char *BufferPointer() { return cb.BufferPointer(); }
+ const char * SCI_METHOD BufferPointer() { return cb.BufferPointer(); }
- int GetLineIndentation(int line);
+ int SCI_METHOD GetLineIndentation(int line);
void SetLineIndentation(int line, int indent);
int GetLineIndentPosition(int line) const;
int GetColumn(int position);
@@ -225,10 +316,13 @@ public:
void DelCharBack(int pos);
char CharAt(int position) { return cb.CharAt(position); }
- void GetCharRange(char *buffer, int position, int lengthRetrieve) {
+ void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const {
cb.GetCharRange(buffer, position, lengthRetrieve);
}
- char StyleAt(int position) { return cb.StyleAt(position); }
+ char SCI_METHOD StyleAt(int position) const { return cb.StyleAt(position); }
+ void GetStyleRange(unsigned char *buffer, int position, int lengthRetrieve) const {
+ cb.GetStyleRange(buffer, position, lengthRetrieve);
+ }
int GetMark(int line);
int AddMark(int line, int markerNum);
void AddMarkSet(int line, int valueSet);
@@ -236,27 +330,29 @@ public:
void DeleteMarkFromHandle(int markerHandle);
void DeleteAllMarks(int markerNum);
int LineFromHandle(int markerHandle);
- int LineStart(int line) const;
+ int SCI_METHOD LineStart(int line) const;
int LineEnd(int line) const;
int LineEndPosition(int position) const;
bool IsLineEndPosition(int position) const;
int VCHomePosition(int position) const;
- int SetLevel(int line, int level);
- int GetLevel(int line);
+ int SCI_METHOD SetLevel(int line, int level);
+ int SCI_METHOD GetLevel(int line) const;
void ClearLevels();
int GetLastChild(int lineParent, int level=-1);
int GetFoldParent(int line);
+ void GetHighlightDelimiters(HighlightDelimiter &hDelimiter, int line, int topLine, int bottomLine);
void Indent(bool forwards);
int ExtendWordSelect(int pos, int delta, bool onlyWordCharacters=false);
int NextWordStart(int pos, int delta);
int NextWordEnd(int pos, int delta);
- int Length() const { return cb.Length(); }
+ int SCI_METHOD Length() const { return cb.Length(); }
void Allocate(int newSize) { cb.Allocate(newSize); }
- long FindText(int minPos, int maxPos, const char *s,
- bool caseSensitive, bool word, bool wordStart, bool regExp, int flags, int *length);
- long FindText(int iMessage, unsigned long wParam, long lParam);
+ size_t ExtractChar(int pos, char *bytes);
+ bool MatchesWordOptions(bool word, bool wordStart, int pos, int length);
+ long FindText(int minPos, int maxPos, const char *search, bool caseSensitive, bool word,
+ bool wordStart, bool regExp, int flags, int *length, CaseFolder *pcf);
const char *SubstituteByPosition(const char *text, int *length);
int LinesTotal() const;
@@ -265,18 +361,23 @@ public:
void SetDefaultCharClasses(bool includeWordClass);
void SetCharClasses(const unsigned char *chars, CharClassify::cc newCharClass);
void SetStylingBits(int bits);
- void StartStyling(int position, char mask);
- bool SetStyleFor(int length, char style);
- bool SetStyles(int length, const char *styles);
+ void SCI_METHOD StartStyling(int position, char mask);
+ bool SCI_METHOD SetStyleFor(int length, char style);
+ bool SCI_METHOD SetStyles(int length, const char *styles);
int GetEndStyled() { return endStyled; }
void EnsureStyledTo(int pos);
+ void LexerChanged();
int GetStyleClock() { return styleClock; }
void IncrementStyleClock();
- void DecorationFillRange(int position, int value, int fillLength);
+ void SCI_METHOD DecorationSetCurrentIndicator(int indicator) {
+ decorations.SetCurrentIndicator(indicator);
+ }
+ void SCI_METHOD DecorationFillRange(int position, int value, int fillLength);
- int SetLineState(int line, int state);
- int GetLineState(int line);
+ int SCI_METHOD SetLineState(int line, int state);
+ int SCI_METHOD GetLineState(int line) const;
int GetMaxLineState();
+ void SCI_METHOD ChangeLexerState(int start, int end);
StyledText MarginStyledText(int line);
void MarginSetStyle(int line, int style);
@@ -299,6 +400,7 @@ public:
const WatcherWithUserData *GetWatchers() const { return watchers; }
int GetLenWatchers() const { return lenWatchers; }
+ CharClassify::cc WordCharClass(unsigned char ch);
bool IsWordPartSeparator(char ch);
int WordPartLeft(int pos);
int WordPartRight(int pos);
@@ -310,7 +412,6 @@ public:
int BraceMatch(int position, int maxReStyle);
private:
- CharClassify::cc WordCharClass(unsigned char ch);
bool IsWordStartAt(int pos);
bool IsWordEndAt(int pos);
bool IsWordAt(int start, int end);
@@ -324,7 +425,7 @@ class UndoGroup {
Document *pdoc;
bool groupNeeded;
public:
- UndoGroup(Document *pdoc_, bool groupNeeded_=true) :
+ UndoGroup(Document *pdoc_, bool groupNeeded_=true) :
pdoc(pdoc_), groupNeeded(groupNeeded_) {
if (groupNeeded) {
pdoc->BeginUndoAction();
@@ -398,6 +499,8 @@ public:
virtual void NotifyModified(Document *doc, DocModification mh, void *userData) = 0;
virtual void NotifyDeleted(Document *doc, void *userData) = 0;
virtual void NotifyStyleNeeded(Document *doc, void *userData, int endPos) = 0;
+ virtual void NotifyLexerChanged(Document *doc, void *userData) = 0;
+ virtual void NotifyErrorOccurred(Document *doc, void *userData, int status) = 0;
};
#ifdef SCI_NAMESPACE
diff --git a/plugins/scintilla/scintilla/Editor.cxx b/plugins/scintilla/scintilla/Editor.cxx
index 9ec5994..d1d0e7f 100644
--- a/plugins/scintilla/scintilla/Editor.cxx
+++ b/plugins/scintilla/scintilla/Editor.cxx
@@ -2,28 +2,23 @@
/** @file Editor.cxx
** Main code for the edit control.
**/
-// Copyright 1998-2004 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <assert.h>
#include <string>
#include <vector>
#include <algorithm>
-
-// With Borland C++ 5.5, including <string> includes Windows.h leading to defining
-// FindText to FindTextA which makes calls here to Document::FindText fail.
-#ifdef __BORLANDC__
-#ifdef FindText
-#undef FindText
-#endif
-#endif
+#include <memory>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
#include "SplitVector.h"
@@ -52,7 +47,7 @@ using namespace Scintilla;
return whether this modification represents an operation that
may reasonably be deferred (not done now OR [possibly] at all)
*/
-static bool CanDeferToLastStep(const DocModification& mh) {
+static bool CanDeferToLastStep(const DocModification &mh) {
if (mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE))
return true; // CAN skip
if (!(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)))
@@ -62,7 +57,7 @@ static bool CanDeferToLastStep(const DocModification& mh) {
return false; // PRESUMABLY must do
}
-static bool CanEliminate(const DocModification& mh) {
+static bool CanEliminate(const DocModification &mh) {
return
(mh.modificationType & (SC_MOD_BEFOREINSERT | SC_MOD_BEFOREDELETE)) != 0;
}
@@ -71,7 +66,7 @@ static bool CanEliminate(const DocModification& mh) {
return whether this modification represents the FINAL step
in a [possibly lengthy] multi-step Undo/Redo sequence
*/
-static bool IsLastStep(const DocModification& mh) {
+static bool IsLastStep(const DocModification &mh) {
return
(mh.modificationType & (SC_PERFORMED_UNDO | SC_PERFORMED_REDO)) != 0
&& (mh.modificationType & SC_MULTISTEPUNDOREDO) != 0
@@ -93,6 +88,15 @@ static inline bool IsControlCharacter(int ch) {
return ch >= 0 && ch < ' ';
}
+static inline bool IsAllSpacesOrTabs(char *s, unsigned int len) {
+ for (unsigned int i = 0; i < len; i++) {
+ // This is safe because IsSpaceOrTab() will return false for null terminators
+ if (!IsSpaceOrTab(s[i]))
+ return false;
+ }
+ return true;
+}
+
Editor::Editor() {
ctrlID = 0;
@@ -123,11 +127,15 @@ Editor::Editor() {
dropWentOutside = false;
posDrag = SelectionPosition(invalidPosition);
posDrop = SelectionPosition(invalidPosition);
+ hotSpotClickPos = INVALID_POSITION;
selectionType = selChar;
lastXChosen = 0;
lineAnchor = 0;
originalAnchorPos = 0;
+ wordSelectAnchorStartPos = 0;
+ wordSelectAnchorEndPos = 0;
+ wordSelectInitialCaretPos = -1;
primarySelection = true;
@@ -147,9 +155,10 @@ Editor::Editor() {
lineWidthMaxSeen = 0;
verticalScrollBarVisible = true;
endAtLastLine = true;
- caretSticky = false;
+ caretSticky = SC_CARETSTICKY_OFF;
multipleSelection = false;
additionalSelectionTyping = false;
+ multiPasteMode = SC_MULTIPASTE_ONCE;
additionalCaretsBlink = true;
additionalCaretsVisible = true;
virtualSpaceOptions = SCVS_NONE;
@@ -169,7 +178,8 @@ Editor::Editor() {
lengthForEncode = -1;
- needUpdateUI = true;
+ needUpdateUI = 0;
+ ContainerNeedsUpdate(SC_UPDATE_CONTENT);
braces[0] = invalidPosition;
braces[1] = invalidPosition;
bracesMatchStyle = STYLE_BRACEBAD;
@@ -428,7 +438,10 @@ int Editor::LineFromLocation(Point pt) {
}
void Editor::SetTopLine(int topLineNew) {
- topLine = topLineNew;
+ if (topLine != topLineNew) {
+ topLine = topLineNew;
+ ContainerNeedsUpdate(SC_UPDATE_V_SCROLL);
+ }
posTopLine = pdoc->LineStart(cs.DocFromDisplay(topLine));
}
@@ -621,7 +634,7 @@ void Editor::Redraw() {
//wMain.InvalidateAll();
}
-void Editor::RedrawSelMargin(int line) {
+void Editor::RedrawSelMargin(int line, bool allAfter) {
if (!AbandonPaint()) {
if (vs.maskInLine) {
Redraw();
@@ -632,7 +645,8 @@ void Editor::RedrawSelMargin(int line) {
int position = pdoc->LineStart(line);
PRectangle rcLine = RectangleFromRange(position, position);
rcSelMargin.top = rcLine.top;
- rcSelMargin.bottom = rcLine.bottom;
+ if (!allAfter)
+ rcSelMargin.bottom = rcLine.bottom;
}
wMain.InvalidateRectangle(rcSelMargin);
}
@@ -691,17 +705,17 @@ void Editor::SetRectangularRange() {
if (sel.selType == Selection::selThin) {
xCaret = xAnchor;
}
- int lineAnchor = pdoc->LineFromPosition(sel.Rectangular().anchor.Position());
+ int lineAnchorRect = pdoc->LineFromPosition(sel.Rectangular().anchor.Position());
int lineCaret = pdoc->LineFromPosition(sel.Rectangular().caret.Position());
- int increment = (lineCaret > lineAnchor) ? 1 : -1;
- for (int line=lineAnchor; line != lineCaret+increment; line += increment) {
+ int increment = (lineCaret > lineAnchorRect) ? 1 : -1;
+ for (int line=lineAnchorRect; line != lineCaret+increment; line += increment) {
SelectionRange range(SPositionFromLineX(line, xCaret), SPositionFromLineX(line, xAnchor));
if ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) == 0)
range.ClearVirtualSpace();
- if (line == lineAnchor)
+ if (line == lineAnchorRect)
sel.SetSelection(range);
else
- sel.AddSelection(range);
+ sel.AddSelectionWithoutTrim(range);
}
}
}
@@ -734,19 +748,36 @@ void Editor::InvalidateSelection(SelectionRange newMain, bool invalidateWholeSel
lastAffected = Platform::Maximum(lastAffected, sel.Range(r).anchor.Position());
}
}
- needUpdateUI = true;
+ ContainerNeedsUpdate(SC_UPDATE_SELECTION);
InvalidateRange(firstAffected, lastAffected);
}
void Editor::SetSelection(SelectionPosition currentPos_, SelectionPosition anchor_) {
- SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_),
- ClampPositionIntoDocument(anchor_));
+ currentPos_ = ClampPositionIntoDocument(currentPos_);
+ anchor_ = ClampPositionIntoDocument(anchor_);
+ int currentLine = pdoc->LineFromPosition(currentPos_.Position());
+ /* For Line selection - ensure the anchor and caret are always
+ at the beginning and end of the region lines. */
+ if (sel.selType == Selection::selLines) {
+ if (currentPos_ > anchor_) {
+ anchor_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(anchor_.Position())));
+ currentPos_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(currentPos_.Position())));
+ } else {
+ currentPos_ = SelectionPosition(pdoc->LineStart(pdoc->LineFromPosition(currentPos_.Position())));
+ anchor_ = SelectionPosition(pdoc->LineEnd(pdoc->LineFromPosition(anchor_.Position())));
+ }
+ }
+ SelectionRange rangeNew(currentPos_, anchor_);
if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
InvalidateSelection(rangeNew);
}
sel.RangeMain() = rangeNew;
SetRectangularRange();
ClaimSelection();
+
+ if (highlightDelimiter.NeedsDrawing(currentLine)) {
+ RedrawSelMargin();
+ }
}
void Editor::SetSelection(int currentPos_, int anchor_) {
@@ -756,6 +787,7 @@ void Editor::SetSelection(int currentPos_, int anchor_) {
// Just move the caret on the main selection
void Editor::SetSelection(SelectionPosition currentPos_) {
currentPos_ = ClampPositionIntoDocument(currentPos_);
+ int currentLine = pdoc->LineFromPosition(currentPos_.Position());
if (sel.Count() > 1 || !(sel.RangeMain().caret == currentPos_)) {
InvalidateSelection(SelectionRange(currentPos_));
}
@@ -768,6 +800,10 @@ void Editor::SetSelection(SelectionPosition currentPos_) {
SelectionRange(SelectionPosition(currentPos_), sel.RangeMain().anchor);
}
ClaimSelection();
+
+ if (highlightDelimiter.NeedsDrawing(currentLine)) {
+ RedrawSelMargin();
+ }
}
void Editor::SetSelection(int currentPos_) {
@@ -775,6 +811,7 @@ void Editor::SetSelection(int currentPos_) {
}
void Editor::SetEmptySelection(SelectionPosition currentPos_) {
+ int currentLine = pdoc->LineFromPosition(currentPos_.Position());
SelectionRange rangeNew(ClampPositionIntoDocument(currentPos_));
if (sel.Count() > 1 || !(sel.RangeMain() == rangeNew)) {
InvalidateSelection(rangeNew);
@@ -784,6 +821,9 @@ void Editor::SetEmptySelection(SelectionPosition currentPos_) {
SetRectangularRange();
ClaimSelection();
+ if (highlightDelimiter.NeedsDrawing(currentLine)) {
+ RedrawSelMargin();
+ }
}
void Editor::SetEmptySelection(int currentPos_) {
@@ -847,9 +887,18 @@ SelectionPosition Editor::MovePositionOutsideChar(SelectionPosition pos, int mov
}
int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, bool ensureVisible) {
+ bool simpleCaret = (sel.Count() == 1) && sel.Empty();
+ SelectionPosition spCaret = sel.Last();
+
int delta = newPos.Position() - sel.MainCaret();
newPos = ClampPositionIntoDocument(newPos);
newPos = MovePositionOutsideChar(newPos, delta);
+ if (!multipleSelection && sel.IsRectangular() && (selt == Selection::selStream)) {
+ // Can't turn into multiple selection so clear additional selections
+ InvalidateSelection(SelectionRange(newPos), true);
+ SelectionRange rangeMain = sel.RangeMain();
+ sel.SetSelection(rangeMain);
+ }
if (!sel.IsRectangular() && (selt == Selection::selRectangle)) {
// Switching to rectangular
SelectionRange rangeMain = sel.RangeMain();
@@ -866,7 +915,20 @@ int Editor::MovePositionTo(SelectionPosition newPos, Selection::selTypes selt, b
}
ShowCaretAtCurrentPosition();
if (ensureVisible) {
- EnsureCaretVisible();
+ XYScrollPosition newXY = XYScrollToMakeVisible(true, true, true);
+ if (simpleCaret && (newXY.xOffset == xOffset)) {
+ // simple vertical scroll then invalidate
+ ScrollTo(newXY.topLine);
+ InvalidateSelection(SelectionRange(spCaret), true);
+ } else {
+ SetXYScroll(newXY);
+ }
+ }
+
+ int currentLine = pdoc->LineFromPosition(newPos.Position());
+
+ if (highlightDelimiter.NeedsDrawing(currentLine)) {
+ RedrawSelMargin();
}
return 0;
}
@@ -908,18 +970,22 @@ Point Editor::PointMainCaret() {
*/
void Editor::SetLastXChosen() {
Point pt = PointMainCaret();
- lastXChosen = pt.x;
+ lastXChosen = pt.x + xOffset;
}
void Editor::ScrollTo(int line, bool moveThumb) {
int topLineNew = Platform::Clamp(line, 0, MaxScrollPos());
if (topLineNew != topLine) {
// Try to optimise small scrolls
+#ifndef UNDER_CE
int linesToMove = topLine - topLineNew;
+#endif
SetTopLine(topLineNew);
- ShowCaretAtCurrentPosition();
- // Perform redraw rather than scroll if many lines would be redrawn anyway.
+ // Optimize by styling the view as this will invalidate any needed area
+ // which could abort the initial paint if discovered later.
+ StyleToPositionInView(PositionAfterArea(GetClientRectangle()));
#ifndef UNDER_CE
+ // Perform redraw rather than scroll if many lines would be redrawn anyway.
if ((abs(linesToMove) <= 10) && (paintState == notPainting)) {
ScrollText(linesToMove);
} else {
@@ -945,22 +1011,86 @@ void Editor::HorizontalScrollTo(int xPos) {
xPos = 0;
if ((wrapState == eWrapNone) && (xOffset != xPos)) {
xOffset = xPos;
+ ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
SetHorizontalScrollPos();
RedrawRect(GetClientRectangle());
}
}
+void Editor::VerticalCentreCaret() {
+ int lineDoc = pdoc->LineFromPosition(sel.IsRectangular() ? sel.Rectangular().caret.Position() : sel.MainCaret());
+ int lineDisplay = cs.DisplayFromDoc(lineDoc);
+ int newTop = lineDisplay - (LinesOnScreen() / 2);
+ if (topLine != newTop) {
+ SetTopLine(newTop > 0 ? newTop : 0);
+ RedrawRect(GetClientRectangle());
+ }
+}
+
+void Editor::MoveSelectedLines(int lineDelta) {
+
+ // if selection doesn't start at the beginning of the line, set the new start
+ int selectionStart = SelectionStart().Position();
+ int startLine = pdoc->LineFromPosition(selectionStart);
+ int beginningOfStartLine = pdoc->LineStart(startLine);
+ selectionStart = beginningOfStartLine;
+
+ // if selection doesn't end at the beginning of a line greater than that of the start,
+ // then set it at the beginning of the next one
+ int selectionEnd = SelectionEnd().Position();
+ int endLine = pdoc->LineFromPosition(selectionEnd);
+ int beginningOfEndLine = pdoc->LineStart(endLine);
+ if (selectionEnd > beginningOfEndLine
+ || selectionStart == selectionEnd) {
+ selectionEnd = pdoc->LineStart(endLine + 1);
+ }
+
+ // if there's nowhere for the selection to move
+ // (i.e. at the beginning going up or at the end going down),
+ // stop it right there!
+ if ((selectionStart == 0 && lineDelta < 0)
+ || (selectionEnd == pdoc->Length() && lineDelta > 0)
+ || selectionStart == selectionEnd) {
+ return;
+ }
+
+ UndoGroup ug(pdoc);
+
+ SetSelection(selectionStart, selectionEnd);
+
+ SelectionText selectedText;
+ CopySelectionRange(&selectedText);
+
+ int selectionLength = SelectionRange(selectionStart, selectionEnd).Length();
+ ClearSelection();
+
+ Point currentLocation = LocationFromPosition(CurrentPosition());
+ int currentLine = LineFromLocation(currentLocation);
+ GoToLine(currentLine + lineDelta);
+
+ pdoc->InsertCString(CurrentPosition(), selectedText.s);
+ SetSelection(CurrentPosition(), CurrentPosition() + selectionLength);
+}
+
+void Editor::MoveSelectedLinesUp() {
+ MoveSelectedLines(-1);
+}
+
+void Editor::MoveSelectedLinesDown() {
+ MoveSelectedLines(1);
+}
+
void Editor::MoveCaretInsideView(bool ensureVisible) {
PRectangle rcClient = GetTextRectangle();
Point pt = PointMainCaret();
if (pt.y < rcClient.top) {
MovePositionTo(SPositionFromLocation(
- Point(lastXChosen, rcClient.top)),
+ Point(lastXChosen - xOffset, rcClient.top)),
Selection::noSel, ensureVisible);
} else if ((pt.y + vs.lineHeight - 1) > rcClient.bottom) {
int yOfLastLineFullyDisplayed = rcClient.top + (LinesOnScreen() - 1) * vs.lineHeight;
MovePositionTo(SPositionFromLocation(
- Point(lastXChosen, rcClient.top + yOfLastLineFullyDisplayed)),
+ Point(lastXChosen - xOffset, rcClient.top + yOfLastLineFullyDisplayed)),
Selection::noSel, ensureVisible);
}
}
@@ -1029,29 +1159,24 @@ slop | strict | jumps | even | Caret can go to the margin | When
1 | 1 | 0 | 1 | No, kept out of UZ | moved by one position
1 | 1 | 1 | 1 | No, kept out of UZ | moved to put caret at 3UZ of the margin
*/
-void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
- //Platform::DebugPrintf("EnsureCaretVisible %d %s\n", xOffset, useMargin ? " margin" : " ");
+
+Editor::XYScrollPosition Editor::XYScrollToMakeVisible(const bool useMargin, const bool vert, const bool horiz) {
PRectangle rcClient = GetTextRectangle();
- //int rcClientFullWidth = rcClient.Width();
- SelectionPosition posCaret = sel.RangeMain().caret;
- if (posDrag.IsValid()) {
- posCaret = posDrag;
- }
- Point pt = LocationFromPosition(posCaret);
- Point ptBottomCaret = pt;
- ptBottomCaret.y += vs.lineHeight - 1;
- int lineCaret = DisplayFromPosition(posCaret.Position());
- bool bSlop, bStrict, bJump, bEven;
+ const SelectionPosition posCaret = posDrag.IsValid() ? posDrag : sel.RangeMain().caret;
+ const Point pt = LocationFromPosition(posCaret);
+ 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)) {
- int linesOnScreen = LinesOnScreen();
- int halfScreen = Platform::Maximum(linesOnScreen - 1, 2) / 2;
- int newTopLine = topLine;
- bSlop = (caretYPolicy & CARET_SLOP) != 0;
- bStrict = (caretYPolicy & CARET_STRICT) != 0;
- bJump = (caretYPolicy & CARET_JUMPS) != 0;
- bEven = (caretYPolicy & CARET_EVEN) != 0;
+ if (vert && (pt.y < rcClient.top || ptBottomCaret.y >= rcClient.bottom || (caretYPolicy & CARET_STRICT) != 0)) {
+ const int linesOnScreen = LinesOnScreen();
+ const int halfScreen = Platform::Maximum(linesOnScreen - 1, 2) / 2;
+ const bool bSlop = (caretYPolicy & CARET_SLOP) != 0;
+ const bool bStrict = (caretYPolicy & CARET_STRICT) != 0;
+ const bool bJump = (caretYPolicy & CARET_JUMPS) != 0;
+ const bool bEven = (caretYPolicy & CARET_EVEN) != 0;
// It should be possible to scroll the window to show the caret,
// but this fails to remove the caret on GTK+
@@ -1084,10 +1209,10 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
}
if (lineCaret < topLine + yMarginT) {
// Caret goes too high
- newTopLine = lineCaret - yMoveT;
+ newXY.topLine = lineCaret - yMoveT;
} else if (lineCaret > topLine + linesOnScreen - 1 - yMarginB) {
// Caret goes too low
- newTopLine = lineCaret - linesOnScreen + 1 + yMoveB;
+ newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB;
}
} else { // Not strict
yMoveT = bJump ? caretYSlop * 3 : caretYSlop;
@@ -1099,10 +1224,10 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
}
if (lineCaret < topLine) {
// Caret goes too high
- newTopLine = lineCaret - yMoveT;
+ newXY.topLine = lineCaret - yMoveT;
} else if (lineCaret > topLine + linesOnScreen - 1) {
// Caret goes too low
- newTopLine = lineCaret - linesOnScreen + 1 + yMoveB;
+ newXY.topLine = lineCaret - linesOnScreen + 1 + yMoveB;
}
}
} else { // No slop
@@ -1110,41 +1235,35 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
// Minimal move
if (lineCaret < topLine) {
// Caret goes too high
- newTopLine = lineCaret;
+ newXY.topLine = lineCaret;
} else if (lineCaret > topLine + linesOnScreen - 1) {
// Caret goes too low
if (bEven) {
- newTopLine = lineCaret - linesOnScreen + 1;
+ newXY.topLine = lineCaret - linesOnScreen + 1;
} else {
- newTopLine = lineCaret;
+ newXY.topLine = lineCaret;
}
}
} else { // Strict or going out of display
if (bEven) {
// Always center caret
- newTopLine = lineCaret - halfScreen;
+ newXY.topLine = lineCaret - halfScreen;
} else {
// Always put caret on top of display
- newTopLine = lineCaret;
+ newXY.topLine = lineCaret;
}
}
}
- newTopLine = Platform::Clamp(newTopLine, 0, MaxScrollPos());
- if (newTopLine != topLine) {
- Redraw();
- SetTopLine(newTopLine);
- SetVerticalScrollPos();
- }
+ newXY.topLine = Platform::Clamp(newXY.topLine, 0, MaxScrollPos());
}
// Horizontal positioning
if (horiz && (wrapState == eWrapNone)) {
- int halfScreen = Platform::Maximum(rcClient.Width() - 4, 4) / 2;
- int xOffsetNew = xOffset;
- bSlop = (caretXPolicy & CARET_SLOP) != 0;
- bStrict = (caretXPolicy & CARET_STRICT) != 0;
- bJump = (caretXPolicy & CARET_JUMPS) != 0;
- bEven = (caretXPolicy & CARET_EVEN) != 0;
+ const int halfScreen = Platform::Maximum(rcClient.Width() - 4, 4) / 2;
+ const bool bSlop = (caretXPolicy & CARET_SLOP) != 0;
+ const bool bStrict = (caretXPolicy & CARET_STRICT) != 0;
+ const bool bJump = (caretXPolicy & CARET_JUMPS) != 0;
+ const bool bEven = (caretXPolicy & CARET_EVEN) != 0;
if (bSlop) { // A margin is defined
int xMoveL, xMoveR;
@@ -1173,18 +1292,18 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
if (pt.x < rcClient.left + xMarginL) {
// Caret is on the left of the display
if (bJump && bEven) {
- xOffsetNew -= xMoveL;
+ newXY.xOffset -= xMoveL;
} else {
// Move just enough to allow to display the caret
- xOffsetNew -= (rcClient.left + xMarginL) - pt.x;
+ newXY.xOffset -= (rcClient.left + xMarginL) - pt.x;
}
} else if (pt.x >= rcClient.right - xMarginR) {
// Caret is on the right of the display
if (bJump && bEven) {
- xOffsetNew += xMoveR;
+ newXY.xOffset += xMoveR;
} else {
// Move just enough to allow to display the caret
- xOffsetNew += pt.x - (rcClient.right - xMarginR) + 1;
+ newXY.xOffset += pt.x - (rcClient.right - xMarginR) + 1;
}
}
} else { // Not strict
@@ -1197,10 +1316,10 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
}
if (pt.x < rcClient.left) {
// Caret is on the left of the display
- xOffsetNew -= xMoveL;
+ newXY.xOffset -= xMoveL;
} else if (pt.x >= rcClient.right) {
// Caret is on the right of the display
- xOffsetNew += xMoveR;
+ newXY.xOffset += xMoveR;
}
}
} else { // No slop
@@ -1209,54 +1328,70 @@ void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
// Strict or going out of display
if (bEven) {
// Center caret
- xOffsetNew += pt.x - rcClient.left - halfScreen;
+ newXY.xOffset += pt.x - rcClient.left - halfScreen;
} else {
// Put caret on right
- xOffsetNew += pt.x - rcClient.right + 1;
+ newXY.xOffset += pt.x - rcClient.right + 1;
}
} else {
// Move just enough to allow to display the caret
if (pt.x < rcClient.left) {
// Caret is on the left of the display
if (bEven) {
- xOffsetNew -= rcClient.left - pt.x;
+ newXY.xOffset -= rcClient.left - pt.x;
} else {
- xOffsetNew += pt.x - rcClient.right + 1;
+ newXY.xOffset += pt.x - rcClient.right + 1;
}
} else if (pt.x >= rcClient.right) {
// Caret is on the right of the display
- xOffsetNew += pt.x - rcClient.right + 1;
+ newXY.xOffset += pt.x - rcClient.right + 1;
}
}
}
// In case of a jump (find result) largely out of display, adjust the offset to display the caret
- if (pt.x + xOffset < rcClient.left + xOffsetNew) {
- xOffsetNew = pt.x + xOffset - rcClient.left;
- } else if (pt.x + xOffset >= rcClient.right + xOffsetNew) {
- xOffsetNew = pt.x + xOffset - rcClient.right + 1;
+ if (pt.x + xOffset < rcClient.left + newXY.xOffset) {
+ newXY.xOffset = pt.x + xOffset - rcClient.left;
+ } else if (pt.x + xOffset >= rcClient.right + newXY.xOffset) {
+ newXY.xOffset = pt.x + xOffset - rcClient.right + 1;
if (vs.caretStyle == CARETSTYLE_BLOCK) {
// Ensure we can see a good portion of the block caret
- xOffsetNew += vs.aveCharWidth;
+ newXY.xOffset += vs.aveCharWidth;
}
}
- if (xOffsetNew < 0) {
- xOffsetNew = 0;
+ if (newXY.xOffset < 0) {
+ newXY.xOffset = 0;
+ }
+ }
+
+ return newXY;
+}
+
+void Editor::SetXYScroll(XYScrollPosition newXY) {
+ if ((newXY.topLine != topLine) || (newXY.xOffset != xOffset)) {
+ if (newXY.topLine != topLine) {
+ SetTopLine(newXY.topLine);
+ SetVerticalScrollPos();
}
- if (xOffset != xOffsetNew) {
- xOffset = xOffsetNew;
- if (xOffsetNew > 0) {
+ if (newXY.xOffset != xOffset) {
+ xOffset = newXY.xOffset;
+ ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
+ if (newXY.xOffset > 0) {
PRectangle rcText = GetTextRectangle();
if (horizontalScrollBarVisible &&
- rcText.Width() + xOffset > scrollWidth) {
+ rcText.Width() + xOffset > scrollWidth) {
scrollWidth = xOffset + rcText.Width();
SetScrollBars();
}
}
SetHorizontalScrollPos();
- Redraw();
}
+ Redraw();
+ UpdateSystemCaret();
}
- UpdateSystemCaret();
+}
+
+void Editor::EnsureCaretVisible(bool useMargin, bool vert, bool horiz) {
+ SetXYScroll(XYScrollToMakeVisible(useMargin, vert, horiz));
}
void Editor::ShowCaretAtCurrentPosition() {
@@ -1369,8 +1504,6 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
rcTextArea.left = vs.fixedColumnWidth;
rcTextArea.right -= vs.rightMarginWidth;
wrapWidth = rcTextArea.Width();
- // Ensure all of the document is styled.
- pdoc->EnsureStyledTo(pdoc->Length());
RefreshStyleData();
AutoSurface surface(this);
if (surface) {
@@ -1391,6 +1524,9 @@ bool Editor::WrapLines(bool fullWrap, int priorityWrapLineStart) {
lastLineToWrap = wrapEnd;
} // else do a fullWrap.
+ // Ensure all lines being wrapped are styled.
+ pdoc->EnsureStyledTo(pdoc->LineEnd(lastLineToWrap));
+
// Platform::DebugPrintf("Wraplines: full = %d, priorityStart = %d (wrapping: %d to %d)\n", fullWrap, priorityWrapLineStart, lineToWrap, lastLineToWrap);
// Platform::DebugPrintf("Pending wraps: %d to %d\n", wrapStart, wrapEnd);
while (lineToWrap < lastLineToWrap) {
@@ -1495,7 +1631,7 @@ static int istrlen(const char *s) {
bool ValidStyledText(ViewStyle &vs, size_t styleOffset, const StyledText &st) {
if (st.multipleStyles) {
- for (size_t iStyle=0;iStyle<st.length; iStyle++) {
+ for (size_t iStyle=0; iStyle<st.length; iStyle++) {
if (!vs.ValidStyle(styleOffset + st.styles[iStyle]))
return false;
}
@@ -1629,7 +1765,6 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
int visibleLine = topLine;
int yposScreen = 0;
-
// 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.
@@ -1647,6 +1782,11 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
needWhiteClosure = true;
}
}
+ if (highlightDelimiter.isEnabled && (vs.ms[margin].mask & SC_MASK_FOLDERS)) {
+ int lineBack = cs.DocFromDisplay(topLine);
+ int lineFront = cs.DocFromDisplay(((rcMargin.bottom - rcMargin.top) / vs.lineHeight) + topLine) + 1;
+ pdoc->GetHighlightDelimiters(highlightDelimiter, pdoc->LineFromPosition(CurrentPosition()), lineBack, lineFront);
+ }
// Old code does not know about new markers needed to distinguish all cases
int folderOpenMid = SubstituteMarkerIfEmpty(SC_MARKNUM_FOLDEROPENMID,
@@ -1657,10 +1797,10 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
while ((visibleLine < cs.LinesDisplayed()) && yposScreen < rcMargin.bottom) {
PLATFORM_ASSERT(visibleLine < cs.LinesDisplayed());
-
int lineDoc = cs.DocFromDisplay(visibleLine);
PLATFORM_ASSERT(cs.GetVisible(lineDoc));
bool firstSubLine = visibleLine == cs.DisplayFromDoc(lineDoc);
+ bool lastSubLine = visibleLine == (cs.DisplayFromDoc(lineDoc + 1) - 1);
// Decide which fold indicator should be displayed
level = pdoc->GetLevel(lineDoc);
@@ -1672,19 +1812,31 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
int levelNextNum = levelNext & SC_FOLDLEVELNUMBERMASK;
if (level & SC_FOLDLEVELHEADERFLAG) {
if (firstSubLine) {
- if (cs.GetExpanded(lineDoc)) {
- if (levelNum == SC_FOLDLEVELBASE)
- marks |= 1 << SC_MARKNUM_FOLDEROPEN;
- else
- marks |= 1 << folderOpenMid;
- } else {
- if (levelNum == SC_FOLDLEVELBASE)
- marks |= 1 << SC_MARKNUM_FOLDER;
- else
- marks |= 1 << folderEnd;
- }
+ if (levelNum < levelNextNum) {
+ if (cs.GetExpanded(lineDoc)) {
+ if (levelNum == SC_FOLDLEVELBASE)
+ marks |= 1 << SC_MARKNUM_FOLDEROPEN;
+ else
+ marks |= 1 << folderOpenMid;
+ } else {
+ if (levelNum == SC_FOLDLEVELBASE)
+ marks |= 1 << SC_MARKNUM_FOLDER;
+ else
+ marks |= 1 << folderEnd;
+ }
+ } else if (levelNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ }
} else {
- marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ if (levelNum < levelNextNum) {
+ if (cs.GetExpanded(lineDoc)) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ } else if (levelNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ }
+ } else if (levelNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
+ }
}
needWhiteClosure = false;
} else if (level & SC_FOLDLEVELWHITEFLAG) {
@@ -1715,16 +1867,19 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
if (levelNext & SC_FOLDLEVELWHITEFLAG) {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
needWhiteClosure = true;
- } else if (levelNextNum > SC_FOLDLEVELBASE) {
- marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
+ } else if (lastSubLine) {
+ if (levelNextNum > SC_FOLDLEVELBASE) {
+ marks |= 1 << SC_MARKNUM_FOLDERMIDTAIL;
+ } else {
+ marks |= 1 << SC_MARKNUM_FOLDERTAIL;
+ }
} else {
- marks |= 1 << SC_MARKNUM_FOLDERTAIL;
+ marks |= 1 << SC_MARKNUM_FOLDERSUB;
}
} else {
marks |= 1 << SC_MARKNUM_FOLDERSUB;
}
}
-
marks &= vs.ms[margin].mask;
PRectangle rcMarker = rcSelMargin;
rcMarker.top = yposScreen;
@@ -1771,7 +1926,20 @@ void Editor::PaintSelMargin(Surface *surfWindow, PRectangle &rc) {
if (marks) {
for (int markBit = 0; (markBit < 32) && marks; markBit++) {
if (marks & 1) {
- vs.markers[markBit].Draw(surface, rcMarker, vs.styles[STYLE_LINENUMBER].font);
+ LineMarker::typeOfFold tFold;
+ if (!highlightDelimiter.isCurrentBlockHighlight(lineDoc)) {
+ tFold = LineMarker::undefined;
+ } else if (highlightDelimiter.isBodyBlockFold(lineDoc)) {
+ tFold = LineMarker::body;
+ } else if (highlightDelimiter.isHeadBlockFold(lineDoc)) {
+ tFold = LineMarker::head;
+ } else if (highlightDelimiter.isTailBlockFold(lineDoc)) {
+ tFold = LineMarker::tail;
+ } else {
+ //Normally, this branch is never used. But I prefer to manage it anyway.
+ tFold = LineMarker::undefined;
+ }
+ vs.markers[markBit].Draw(surface, rcMarker, vs.styles[STYLE_LINENUMBER].font, tFold);
}
marks >>= 1;
}
@@ -1824,6 +1992,7 @@ static bool GoodTrailByte(int v) {
}
bool BadUTF(const char *s, int len, int &trailBytes) {
+ // For the rules: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
if (trailBytes) {
trailBytes--;
return false;
@@ -1840,6 +2009,23 @@ bool BadUTF(const char *s, int len, int &trailBytes) {
if (len < 4)
return true;
if (GoodTrailByte(us[1]) && GoodTrailByte(us[2]) && GoodTrailByte(us[3])) {
+ if (*us == 0xf4) {
+ // Check if encoding a value beyond the last Unicode character 10FFFF
+ if (us[1] > 0x8f) {
+ return true;
+ } else if (us[1] == 0x8f) {
+ if (us[2] > 0xbf) {
+ return true;
+ } else if (us[2] == 0xbf) {
+ if (us[3] > 0xbf) {
+ return true;
+ }
+ }
+ }
+ } else if ((*us == 0xf0) && ((us[1] & 0xf0) == 0x80)) {
+ // Overlong
+ return true;
+ }
trailBytes = 3;
return false;
} else {
@@ -1850,6 +2036,22 @@ bool BadUTF(const char *s, int len, int &trailBytes) {
if (len < 3)
return true;
if (GoodTrailByte(us[1]) && GoodTrailByte(us[2])) {
+ if ((*us == 0xe0) && ((us[1] & 0xe0) == 0x80)) {
+ // Overlong
+ return true;
+ }
+ if ((*us == 0xed) && ((us[1] & 0xe0) == 0xa0)) {
+ // Surrogate
+ return true;
+ }
+ if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbe)) {
+ // U+FFFE
+ return true;
+ }
+ if ((*us == 0xef) && (us[1] == 0xbf) && (us[2] == 0xbf)) {
+ // U+FFFF
+ return true;
+ }
trailBytes = 2;
return false;
} else {
@@ -1939,8 +2141,6 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
if (ll->validity == LineLayout::llInvalid) {
ll->widthLine = LineLayout::wrapWidthInfinite;
ll->lines = 1;
- int numCharsInLine = 0;
- int numCharsBeforeEOL = 0;
if (vstyle.edgeState == EDGE_BACKGROUND) {
ll->edgeColumn = pdoc->FindColumn(line, theEdge);
if (ll->edgeColumn >= posLineStart) {
@@ -1950,25 +2150,32 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
ll->edgeColumn = -1;
}
- char styleByte = 0;
- int styleMask = pdoc->stylingBitsMask;
+ char styleByte;
+ const int styleMask = pdoc->stylingBitsMask;
ll->styleBitsSet = 0;
// Fill base line layout
- for (int charInDoc = posLineStart; charInDoc < posLineEnd; charInDoc++) {
- char chDoc = pdoc->CharAt(charInDoc);
- styleByte = pdoc->StyleAt(charInDoc);
+ const int lineLength = posLineEnd - posLineStart;
+ pdoc->GetCharRange(ll->chars, posLineStart, lineLength);
+ pdoc->GetStyleRange(ll->styles, posLineStart, lineLength);
+ int numCharsBeforeEOL = lineLength;
+ while ((numCharsBeforeEOL > 0) && IsEOLChar(ll->chars[numCharsBeforeEOL-1])) {
+ numCharsBeforeEOL--;
+ }
+ const int numCharsInLine = (vstyle.viewEOL) ? lineLength : numCharsBeforeEOL;
+ for (int styleInLine = 0; styleInLine < numCharsInLine; styleInLine++) {
+ styleByte = ll->styles[styleInLine];
ll->styleBitsSet |= styleByte;
- if (vstyle.viewEOL || (!IsEOLChar(chDoc))) {
- ll->chars[numCharsInLine] = chDoc;
- ll->styles[numCharsInLine] = static_cast<char>(styleByte & styleMask);
- ll->indicators[numCharsInLine] = static_cast<char>(styleByte & ~styleMask);
- if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseUpper)
- ll->chars[numCharsInLine] = static_cast<char>(toupper(chDoc));
- else if (vstyle.styles[ll->styles[numCharsInLine]].caseForce == Style::caseLower)
- ll->chars[numCharsInLine] = static_cast<char>(tolower(chDoc));
- numCharsInLine++;
- if (!IsEOLChar(chDoc))
- numCharsBeforeEOL++;
+ ll->styles[styleInLine] = static_cast<char>(styleByte & styleMask);
+ ll->indicators[styleInLine] = static_cast<char>(styleByte & ~styleMask);
+ }
+ styleByte = static_cast<char>(((lineLength > 0) ? ll->styles[lineLength-1] : 0) & styleMask);
+ if (vstyle.someStylesForceCase) {
+ for (int charInLine = 0; charInLine<lineLength; charInLine++) {
+ char chDoc = ll->chars[charInLine];
+ if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseUpper)
+ ll->chars[charInLine] = static_cast<char>(toupper(chDoc));
+ else if (vstyle.styles[ll->styles[charInLine]].caseForce == Style::caseLower)
+ ll->chars[charInLine] = static_cast<char>(tolower(chDoc));
}
}
ll->xHighlightGuide = 0;
@@ -2018,8 +2225,8 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
}
lastSegItalics = false;
} else if (isBadUTF) {
- char hexits[3];
- sprintf(hexits, "%2X", ll->chars[charInLine] & 0xff);
+ char hexits[4];
+ sprintf(hexits, "x%2X", ll->chars[charInLine] & 0xff);
ll->positions[charInLine + 1] =
surface->WidthText(ctrlCharsFont, hexits, istrlen(hexits)) + 3;
} else { // Regular character
@@ -2031,7 +2238,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
} else {
lastSegItalics = vstyle.styles[ll->styles[charInLine]].italic;
posCache.MeasureWidths(surface, vstyle, ll->styles[charInLine], ll->chars + startseg,
- lenSeg, ll->positions + startseg + 1);
+ lenSeg, ll->positions + startseg + 1, pdoc);
}
}
} else { // invisible
@@ -2342,6 +2549,8 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
// Fill the remainder of the line
rcSegment.left = xEol + xStart + virtualSpace + blobsWidth + vsDraw.aveCharWidth;
+ if (rcSegment.left < rcLine.left)
+ rcSegment.left = rcLine.left;
rcSegment.right = rcLine.right;
if (!hideSelection && vsDraw.selEOLFilled && eolInSelection && vsDraw.selbackset && (line < pdoc->LinesTotal() - 1) && (alpha == SC_ALPHA_NOALPHA)) {
@@ -2374,12 +2583,22 @@ void Editor::DrawEOL(Surface *surface, ViewStyle &vsDraw, PRectangle rcLine, Lin
}
}
+void Editor::DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
+ int xStart, PRectangle rcLine, LineLayout *ll, int subLine) {
+ const int subLineStart = ll->positions[ll->LineStart(subLine)];
+ PRectangle rcIndic(
+ ll->positions[startPos] + xStart - subLineStart,
+ rcLine.top + vsDraw.maxAscent,
+ ll->positions[endPos] + xStart - subLineStart,
+ rcLine.top + vsDraw.maxAscent + 3);
+ vsDraw.indicators[indicNum].Draw(surface, rcIndic, rcLine);
+}
+
void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under) {
// Draw decorators
const int posLineStart = pdoc->LineStart(line);
const int lineStart = ll->LineStart(subLine);
- const int subLineStart = ll->positions[lineStart];
const int posLineEnd = posLineStart + lineEnd;
if (!under) {
@@ -2404,12 +2623,7 @@ void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int x
// IN indicator run, looking for END
if (indicPos >= lineEnd || !(ll->indicators[indicPos] & mask)) {
// AT end of indicator run, DRAW it!
- PRectangle rcIndic(
- ll->positions[startPos] + xStart - subLineStart,
- rcLine.top + vsDraw.maxAscent,
- ll->positions[indicPos] + xStart - subLineStart,
- rcLine.top + vsDraw.maxAscent + 3);
- vsDraw.indicators[indicnum].Draw(surface, rcIndic, rcLine);
+ DrawIndicator(indicnum, startPos, indicPos, surface, vsDraw, xStart, rcLine, ll, subLine);
// RESET control var
startPos = -1;
}
@@ -2429,16 +2643,33 @@ void Editor::DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int x
int endPos = deco->rs.EndRun(startPos);
if (endPos > posLineEnd)
endPos = posLineEnd;
- PRectangle rcIndic(
- ll->positions[startPos - posLineStart] + xStart - subLineStart,
- rcLine.top + vsDraw.maxAscent,
- ll->positions[endPos - posLineStart] + xStart - subLineStart,
- rcLine.top + vsDraw.maxAscent + 3);
- vsDraw.indicators[deco->indicator].Draw(surface, rcIndic, rcLine);
+ DrawIndicator(deco->indicator, startPos - posLineStart, endPos - posLineStart,
+ surface, vsDraw, xStart, rcLine, ll, subLine);
startPos = deco->rs.EndRun(endPos);
}
}
}
+
+ // Use indicators to highlight matching braces
+ if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) ||
+ (vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) {
+ int braceIndicator = (bracesMatchStyle == STYLE_BRACELIGHT) ? vs.braceHighlightIndicator : vs.braceBadLightIndicator;
+ if (under == vsDraw.indicators[braceIndicator].under) {
+ Range rangeLine(posLineStart + lineStart, posLineEnd);
+ if (rangeLine.ContainsCharacter(braces[0])) {
+ int braceOffset = braces[0] - posLineStart;
+ if (braceOffset < ll->numCharsInLine) {
+ DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine);
+ }
+ }
+ if (rangeLine.ContainsCharacter(braces[1])) {
+ int braceOffset = braces[1] - posLineStart;
+ if (braceOffset < ll->numCharsInLine) {
+ DrawIndicator(braceIndicator, braceOffset, braceOffset + 1, surface, vsDraw, xStart, rcLine, ll, subLine);
+ }
+ }
+ }
+ }
}
void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
@@ -2481,7 +2712,7 @@ void Editor::DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int x
surface->LineTo(rcSegment.left, rcSegment.bottom);
surface->MoveTo(rcSegment.right, rcSegment.top);
surface->LineTo(rcSegment.right, rcSegment.bottom);
- if (subLine == ll->lines){
+ if (subLine == ll->lines) {
surface->MoveTo(rcSegment.left, rcSegment.top);
surface->LineTo(rcSegment.right, rcSegment.top);
}
@@ -2623,7 +2854,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
ll->psel = &sel;
- BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible, selBackDrawn);
+ BreakFinder bfBack(ll, lineStart, lineEnd, posLineStart, xStartVisible, selBackDrawn, pdoc);
int next = bfBack.First();
// Background drawing loop
@@ -2713,8 +2944,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
inIndentation = subLine == 0; // Do not handle indentation except on first subline.
// Foreground drawing loop
- BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, IsUnicodeMode(), xStartVisible,
- ((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset));
+ BreakFinder bfFore(ll, lineStart, lineEnd, posLineStart, xStartVisible,
+ ((!twoPhaseDraw && selBackDrawn) || vsDraw.selforeset), pdoc);
next = bfFore.First();
while (next < lineEnd) {
@@ -2787,8 +3018,9 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
cc, 1, textBack, textFore);
}
} else if ((i == startseg) && (static_cast<unsigned char>(ll->chars[i]) >= 0x80) && IsUnicodeMode()) {
- char hexits[3];
- sprintf(hexits, "%2X", ll->chars[i] & 0xff);
+ // A single byte >= 0x80 in UTF-8 is a bad byte and is displayed as its hex value
+ char hexits[4];
+ sprintf(hexits, "x%2X", ll->chars[i] & 0xff);
DrawTextBlob(surface, vsDraw, rcSegment, hexits, textBack, textFore, twoPhaseDraw);
} else {
// Normal text display
@@ -2840,7 +3072,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
}
}
}
- if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd ) {
+ if (ll->hsStart != -1 && vsDraw.hotspotUnderline && iDoc >= ll->hsStart && iDoc < ll->hsEnd) {
PRectangle rcUL = rcSegment;
rcUL.top = rcUL.top + vsDraw.maxAscent + 1;
rcUL.bottom = rcUL.top + 1;
@@ -2893,7 +3125,8 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
lineNextWithText++;
}
if (lineNextWithText > line) {
- // This line is empty, so use indentation of last line with text
+ xStartText = 100000; // Don't limit to visible indentation on empty line
+ // This line is empty, so use indentation of first next line with text
indentSpace = Platform::Maximum(indentSpace,
pdoc->GetLineIndentation(lineNextWithText));
}
@@ -2941,7 +3174,7 @@ void Editor::DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVis
}
// Draw any translucent whole line states
- rcSegment.left = xStart;
+ rcSegment.left = 0;
rcSegment.right = rcLine.right - 1;
if (caret.active && vsDraw.showCaretLineBackground && ll->containsCaret) {
SimpleAlphaRectangle(surface, rcSegment, vsDraw.caretLineBackground.allocated, vsDraw.caretLineAlpha);
@@ -3063,11 +3296,11 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
}
pixmapSelPattern->FillRectangle(rcPattern, colourFMFill);
- pixmapSelPattern->PenColour(colourFMStripes);
- for (int stripe = 0; stripe < patternSize; stripe++) {
- // Alternating 1 pixel stripes is same as checkerboard.
- pixmapSelPattern->MoveTo(0, stripe * 2);
- pixmapSelPattern->LineTo(patternSize, stripe * 2 - patternSize);
+ 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);
+ }
}
}
@@ -3081,10 +3314,9 @@ void Editor::RefreshPixMaps(Surface *surfaceWindow) {
pixmapIndentGuideHighlight->FillRectangle(rcIG, vs.styles[STYLE_BRACELIGHT].back.allocated);
pixmapIndentGuideHighlight->PenColour(vs.styles[STYLE_BRACELIGHT].fore.allocated);
for (int stripe = 1; stripe < vs.lineHeight + 1; stripe += 2) {
- pixmapIndentGuide->MoveTo(0, stripe);
- pixmapIndentGuide->LineTo(2, stripe);
- pixmapIndentGuideHighlight->MoveTo(0, stripe);
- pixmapIndentGuideHighlight->LineTo(2, stripe);
+ PRectangle rcPixel(0, stripe, 1, stripe+1);
+ pixmapIndentGuide->FillRectangle(rcPixel, vs.styles[STYLE_INDENTGUIDE].fore.allocated);
+ pixmapIndentGuideHighlight->FillRectangle(rcPixel, vs.styles[STYLE_BRACELIGHT].fore.allocated);
}
}
@@ -3186,6 +3418,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
//Platform::DebugPrintf("Paint:%1d (%3d,%3d) ... (%3d,%3d)\n",
// paintingAllText, rcArea.left, rcArea.top, rcArea.right, rcArea.bottom);
+ StyleToPositionInView(PositionAfterArea(rcArea));
+
pixmapLine->Release();
RefreshStyleData();
RefreshPixMaps(surfaceWindow);
@@ -3198,13 +3432,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
pixmapLine->SetPalette(&palette, !hasFocus);
int screenLinePaintFirst = rcArea.top / vs.lineHeight;
- // The area to be painted plus one extra line is styled.
- // The extra line is to determine when a style change, such as starting a comment flows on to other lines.
- int lineStyleLast = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1;
- //Platform::DebugPrintf("Paint lines = %d .. %d\n", topLine + screenLinePaintFirst, lineStyleLast);
- int endPosPaint = pdoc->Length();
- if (lineStyleLast < cs.LinesDisplayed())
- endPosPaint = pdoc->LineStart(cs.DocFromDisplay(lineStyleLast) + 1);
int xStart = vs.fixedColumnWidth - xOffset;
int ypos = 0;
@@ -3212,8 +3439,6 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
ypos += screenLinePaintFirst * vs.lineHeight;
int yposScreen = screenLinePaintFirst * vs.lineHeight;
- // Ensure we are styled as far as we are painting.
- pdoc->EnsureStyledTo(endPosPaint);
bool paintAbandonedByStyling = paintState == paintAbandoned;
if (needUpdateUI) {
// Deselect palette by selecting a temporary palette
@@ -3221,7 +3446,7 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
surfaceWindow->SetPalette(&palTemp, true);
NotifyUpdateUI();
- needUpdateUI = false;
+ needUpdateUI = 0;
RefreshStyleData();
RefreshPixMaps(surfaceWindow);
@@ -3245,12 +3470,14 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
}
PLATFORM_ASSERT(pixmapSelPattern->Initialised());
- PaintSelMargin(surfaceWindow, 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.allocated);
+ PRectangle rcRightMargin = rcClient;
+ rcRightMargin.left = rcRightMargin.right - vs.rightMarginWidth;
+ if (rcArea.Intersects(rcRightMargin)) {
+ surfaceWindow->FillRectangle(rcRightMargin, vs.styles[STYLE_DEFAULT].back.allocated);
+ }
}
if (paintState == paintAbandoned) {
@@ -3331,34 +3558,40 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
rcLine.top = ypos;
rcLine.bottom = ypos + vs.lineHeight;
+ bool bracesIgnoreStyle = false;
+ if ((vs.braceHighlightIndicatorSet && (bracesMatchStyle == STYLE_BRACELIGHT)) ||
+ (vs.braceBadLightIndicatorSet && (bracesMatchStyle == STYLE_BRACEBAD))) {
+ bracesIgnoreStyle = true;
+ }
Range rangeLine(pdoc->LineStart(lineDoc), pdoc->LineStart(lineDoc + 1));
// Highlight the current braces if any
ll->SetBracesHighlight(rangeLine, braces, static_cast<char>(bracesMatchStyle),
- highlightGuideColumn * vs.spaceWidth);
+ highlightGuideColumn * vs.spaceWidth, bracesIgnoreStyle);
// Draw the line
DrawLine(surface, vs, lineDoc, visibleLine, xStart, rcLine, ll, subLine);
//durPaint += et.Duration(true);
// Restore the previous styles for the brace highlights in case layout is in cache.
- ll->RestoreBracesHighlight(rangeLine, braces);
+ ll->RestoreBracesHighlight(rangeLine, braces, bracesIgnoreStyle);
bool expanded = cs.GetExpanded(lineDoc);
- // Paint the line above the fold
- if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
- ||
- (!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
- if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+ const int level = pdoc->GetLevel(lineDoc);
+ const int levelNext = pdoc->GetLevel(lineDoc + 1);
+ if ((level & SC_FOLDLEVELHEADERFLAG) &&
+ ((level & SC_FOLDLEVELNUMBERMASK) < (levelNext & SC_FOLDLEVELNUMBERMASK))) {
+ // Paint the line above the fold
+ if ((expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_EXPANDED))
+ ||
+ (!expanded && (foldFlags & SC_FOLDFLAG_LINEBEFORE_CONTRACTED))) {
PRectangle rcFoldLine = rcLine;
rcFoldLine.bottom = rcFoldLine.top + 1;
surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
}
- }
- // Paint the line below the fold
- if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
- ||
- (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
- if (pdoc->GetLevel(lineDoc) & SC_FOLDLEVELHEADERFLAG) {
+ // Paint the line below the fold
+ if ((expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_EXPANDED))
+ ||
+ (!expanded && (foldFlags & SC_FOLDFLAG_LINEAFTER_CONTRACTED))) {
PRectangle rcFoldLine = rcLine;
rcFoldLine.top = rcFoldLine.bottom - 1;
surface->FillRectangle(rcFoldLine, vs.styles[STYLE_DEFAULT].fore.allocated);
@@ -3472,9 +3705,12 @@ long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
vsPrint.whitespaceBackgroundSet = false;
vsPrint.whitespaceForegroundSet = false;
vsPrint.showCaretLineBackground = false;
+ // Don't highlight matching braces using indicators
+ vsPrint.braceHighlightIndicatorSet = false;
+ vsPrint.braceBadLightIndicatorSet = false;
// Set colours for printing according to users settings
- for (size_t sty = 0;sty < vsPrint.stylesSize;sty++) {
+ for (size_t sty = 0; sty < vsPrint.stylesSize; sty++) {
if (printColourMode == SC_PRINT_INVERTLIGHT) {
vsPrint.styles[sty].fore.desired = InvertedLight(vsPrint.styles[sty].fore.desired);
vsPrint.styles[sty].back.desired = InvertedLight(vsPrint.styles[sty].back.desired);
@@ -3529,7 +3765,7 @@ long Editor::FormatRange(bool draw, Sci_RangeToFormat *pfr) {
int nPrintPos = pfr->chrg.cpMin;
int visibleLine = 0;
- int widthPrint = pfr->rc.Width() - vsPrint.fixedColumnWidth;
+ int widthPrint = pfr->rc.right - pfr->rc.left - vsPrint.fixedColumnWidth;
if (printWrapState == eWrapNone)
widthPrint = LineLayout::wrapWidthInfinite;
@@ -3727,7 +3963,11 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
if (wrapState != eWrapNone) {
AutoSurface surface(this);
if (surface) {
- WrapOneLine(surface, pdoc->LineFromPosition(positionInsert));
+ if (WrapOneLine(surface, pdoc->LineFromPosition(positionInsert))) {
+ SetScrollBars();
+ SetVerticalScrollPos();
+ Redraw();
+ }
}
}
}
@@ -3741,7 +3981,8 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
EnsureCaretVisible();
// Avoid blinking during rapid typing:
ShowCaretAtCurrentPosition();
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) ||
+ ((caretSticky == SC_CARETSTICKY_WHITESPACE) && !IsAllSpacesOrTabs(s, len))) {
SetLastXChosen();
}
@@ -3787,8 +4028,40 @@ void Editor::AddCharUTF(char *s, unsigned int len, bool treatAsDBCS) {
}
}
-void Editor::ClearSelection() {
- if (!sel.IsRectangular())
+void Editor::InsertPaste(SelectionPosition selStart, const char *text, int len) {
+ if (multiPasteMode == SC_MULTIPASTE_ONCE) {
+ selStart = SelectionPosition(InsertSpace(selStart.Position(), selStart.VirtualSpace()));
+ if (pdoc->InsertString(selStart.Position(), text, len)) {
+ SetEmptySelection(selStart.Position() + len);
+ }
+ } else {
+ // SC_MULTIPASTE_EACH
+ for (size_t r=0; r<sel.Count(); r++) {
+ if (!RangeContainsProtected(sel.Range(r).Start().Position(),
+ sel.Range(r).End().Position())) {
+ int positionInsert = sel.Range(r).Start().Position();
+ if (!sel.Range(r).Empty()) {
+ if (sel.Range(r).Length()) {
+ pdoc->DeleteChars(positionInsert, sel.Range(r).Length());
+ sel.Range(r).ClearVirtualSpace();
+ } else {
+ // Range is all virtual so collapse to start of virtual space
+ sel.Range(r).MinimizeVirtualSpace();
+ }
+ }
+ positionInsert = InsertSpace(positionInsert, sel.Range(r).caret.VirtualSpace());
+ if (pdoc->InsertString(positionInsert, text, len)) {
+ sel.Range(r).caret.SetPosition(positionInsert + len);
+ sel.Range(r).anchor.SetPosition(positionInsert + len);
+ }
+ sel.Range(r).ClearVirtualSpace();
+ }
+ }
+ }
+}
+
+void Editor::ClearSelection(bool retainMultipleSelections) {
+ if (!sel.IsRectangular() && !retainMultipleSelections)
FilterSelections();
UndoGroup ug(pdoc);
for (size_t r=0; r<sel.Count(); r++) {
@@ -3902,9 +4175,9 @@ bool Editor::CanPaste() {
}
void Editor::Clear() {
- UndoGroup ug(pdoc);
// If multiple selections, don't delete EOLS
if (sel.Empty()) {
+ UndoGroup ug(pdoc, sel.Count() > 1);
for (size_t r=0; r<sel.Count(); r++) {
if (!RangeContainsProtected(sel.Range(r).caret.Position(), sel.Range(r).caret.Position() + 1)) {
if (sel.Range(r).Start().VirtualSpace()) {
@@ -4014,10 +4287,17 @@ void Editor::NotifyStyleToNeeded(int endStyleNeeded) {
NotifyParent(scn);
}
-void Editor::NotifyStyleNeeded(Document*, void *, int endStyleNeeded) {
+void Editor::NotifyStyleNeeded(Document *, void *, int endStyleNeeded) {
NotifyStyleToNeeded(endStyleNeeded);
}
+void Editor::NotifyLexerChanged(Document *, void *) {
+}
+
+void Editor::NotifyErrorOccurred(Document *, void *, int status) {
+ errorStatus = status;
+}
+
void Editor::NotifyChar(int ch) {
SCNotification scn = {0};
scn.nmhdr.code = SCN_CHARADDED;
@@ -4069,9 +4349,19 @@ void Editor::NotifyHotSpotClicked(int position, bool shift, bool ctrl, bool alt)
NotifyParent(scn);
}
+void Editor::NotifyHotSpotReleaseClick(int position, bool shift, bool ctrl, bool alt) {
+ SCNotification scn = {0};
+ scn.nmhdr.code = SCN_HOTSPOTRELEASECLICK;
+ scn.position = position;
+ scn.modifiers = (shift ? SCI_SHIFT : 0) | (ctrl ? SCI_CTRL : 0) |
+ (alt ? SCI_ALT : 0);
+ NotifyParent(scn);
+}
+
void Editor::NotifyUpdateUI() {
SCNotification scn = {0};
scn.nmhdr.code = SCN_UPDATEUI;
+ scn.updated = needUpdateUI;
NotifyParent(scn);
}
@@ -4139,12 +4429,12 @@ void Editor::NotifyZoom() {
}
// Notifications from document
-void Editor::NotifyModifyAttempt(Document*, void *) {
+void Editor::NotifyModifyAttempt(Document *, void *) {
//Platform::DebugPrintf("** Modify Attempt\n");
NotifyModifyAttempt();
}
-void Editor::NotifySavePoint(Document*, void *, bool atSavePoint) {
+void Editor::NotifySavePoint(Document *, void *, bool atSavePoint) {
//Platform::DebugPrintf("** Save Point %s\n", atSavePoint ? "On" : "Off");
NotifySavePoint(atSavePoint);
}
@@ -4187,8 +4477,8 @@ static inline int MovePositionForDeletion(int position, int startDeletion, int l
}
}
-void Editor::NotifyModified(Document*, DocModification mh, void *) {
- needUpdateUI = true;
+void Editor::NotifyModified(Document *, DocModification mh, void *) {
+ ContainerNeedsUpdate(SC_UPDATE_CONTENT);
if (paintState == painting) {
CheckForChangeOutsidePaint(Range(mh.position, mh.position + mh.length));
}
@@ -4201,6 +4491,14 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
Redraw();
}
}
+ if (mh.modificationType & SC_MOD_LEXERSTATE) {
+ if (paintState == painting) {
+ CheckForChangeOutsidePaint(
+ Range(mh.position, mh.position + mh.length));
+ } else {
+ Redraw();
+ }
+ }
if (mh.modificationType & (SC_MOD_CHANGESTYLE | SC_MOD_CHANGEINDICATOR)) {
if (mh.modificationType & SC_MOD_CHANGESTYLE) {
pdoc->IncrementStyleClock();
@@ -4231,7 +4529,16 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
// Some lines are hidden so may need shown.
// TODO: check if the modified area is hidden.
if (mh.modificationType & SC_MOD_BEFOREINSERT) {
- NotifyNeedShown(mh.position, 0);
+ int lineOfPos = pdoc->LineFromPosition(mh.position);
+ bool insertingNewLine = false;
+ for (int i=0; i < mh.length; i++) {
+ if ((mh.text[i] == '\n') || (mh.text[i] == '\r'))
+ insertingNewLine = true;
+ }
+ if (insertingNewLine && (mh.position != pdoc->LineStart(lineOfPos)))
+ NotifyNeedShown(mh.position, pdoc->LineStart(lineOfPos+1) - mh.position);
+ else
+ NotifyNeedShown(mh.position, 0);
} else if (mh.modificationType & SC_MOD_BEFOREDELETE) {
NotifyNeedShown(mh.position, mh.length);
}
@@ -4250,6 +4557,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
int lineDoc = pdoc->LineFromPosition(mh.position);
if (vs.annotationVisible) {
cs.SetHeight(lineDoc, cs.GetHeight(lineDoc) + mh.annotationLinesAdded);
+ Redraw();
}
}
CheckModificationForWrap(mh);
@@ -4267,12 +4575,14 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
// 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());
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);
InvalidateRange(mh.position, mh.position + mh.length);
}
}
@@ -4286,7 +4596,7 @@ void Editor::NotifyModified(Document*, DocModification mh, void *) {
if ((paintState == notPainting) || !PaintContainsMargin()) {
if (mh.modificationType & SC_MOD_CHANGEFOLD) {
// Fold changes can affect the drawing of following lines so redraw whole margin
- RedrawSelMargin();
+ RedrawSelMargin(mh.line-1, true);
} else {
RedrawSelMargin(mh.line);
}
@@ -4430,6 +4740,9 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
case SCI_PAGEDOWNRECTEXTEND:
case SCI_SELECTIONDUPLICATE:
case SCI_COPYALLOWLINE:
+ case SCI_VERTICALCENTRECARET:
+ case SCI_MOVESELECTEDLINESUP:
+ case SCI_MOVESELECTEDLINESDOWN:
break;
// Filter out all others like display changes. Also, newlines are redundant
@@ -4449,6 +4762,11 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
NotifyParent(scn);
}
+// Something has changed that the container should know about
+void Editor::ContainerNeedsUpdate(int flags) {
+ needUpdateUI |= flags;
+}
+
/**
* Force scroll and keep position relative to top of window.
*
@@ -4456,51 +4774,76 @@ void Editor::NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lPar
* If stuttered = true and already at first/last row, scroll as normal.
*/
void Editor::PageMove(int direction, Selection::selTypes selt, bool stuttered) {
- int topLineNew, newPos;
+ int topLineNew;
+ SelectionPosition newPos;
- // I consider only the caretYSlop, and ignore the caretYPolicy-- is that a problem?
int currentLine = pdoc->LineFromPosition(sel.MainCaret());
int topStutterLine = topLine + caretYSlop;
int bottomStutterLine =
pdoc->LineFromPosition(PositionFromLocation(
- Point(lastXChosen, direction * vs.lineHeight * LinesToScroll())))
+ Point(lastXChosen - xOffset, direction * vs.lineHeight * LinesToScroll())))
- caretYSlop - 1;
if (stuttered && (direction < 0 && currentLine > topStutterLine)) {
topLineNew = topLine;
- newPos = PositionFromLocation(Point(lastXChosen, vs.lineHeight * caretYSlop));
+ newPos = SPositionFromLocation(Point(lastXChosen - xOffset, vs.lineHeight * caretYSlop),
+ false, false, UserVirtualSpace());
} else if (stuttered && (direction > 0 && currentLine < bottomStutterLine)) {
topLineNew = topLine;
- newPos = PositionFromLocation(Point(lastXChosen, vs.lineHeight * (LinesToScroll() - caretYSlop)));
+ newPos = SPositionFromLocation(Point(lastXChosen - xOffset, vs.lineHeight * (LinesToScroll() - caretYSlop)),
+ false, false, UserVirtualSpace());
} else {
Point pt = LocationFromPosition(sel.MainCaret());
topLineNew = Platform::Clamp(
topLine + direction * LinesToScroll(), 0, MaxScrollPos());
- newPos = PositionFromLocation(
- Point(lastXChosen, pt.y + direction * (vs.lineHeight * LinesToScroll())));
+ newPos = SPositionFromLocation(
+ Point(lastXChosen - xOffset, pt.y + direction * (vs.lineHeight * LinesToScroll())),
+ false, false, UserVirtualSpace());
}
if (topLineNew != topLine) {
SetTopLine(topLineNew);
- MovePositionTo(SelectionPosition(newPos), selt);
+ MovePositionTo(newPos, selt);
Redraw();
SetVerticalScrollPos();
} else {
- MovePositionTo(SelectionPosition(newPos), selt);
+ MovePositionTo(newPos, selt);
}
}
-void Editor::ChangeCaseOfSelection(bool makeUpperCase) {
+void Editor::ChangeCaseOfSelection(int caseMapping) {
UndoGroup ug(pdoc);
for (size_t r=0; r<sel.Count(); r++) {
SelectionRange current = sel.Range(r);
- pdoc->ChangeCase(Range(current.Start().Position(), current.End().Position()),
- makeUpperCase);
- // Automatic movement cuts off last character so reset to exactly the same as it was.
- sel.Range(r) = current;
+ SelectionRange currentNoVS = current;
+ currentNoVS.ClearVirtualSpace();
+ char *text = CopyRange(currentNoVS.Start().Position(), currentNoVS.End().Position());
+ size_t rangeBytes = currentNoVS.Length();
+ if (rangeBytes > 0) {
+ std::string sText(text, rangeBytes);
+
+ std::string sMapped = CaseMapString(sText, caseMapping);
+
+ if (sMapped != sText) {
+ size_t firstDifference = 0;
+ while (sMapped[firstDifference] == sText[firstDifference])
+ firstDifference++;
+ size_t lastDifference = sMapped.size() - 1;
+ while (sMapped[lastDifference] == sText[lastDifference])
+ lastDifference--;
+ size_t endSame = sMapped.size() - 1 - lastDifference;
+ pdoc->DeleteChars(currentNoVS.Start().Position() + firstDifference,
+ rangeBytes - firstDifference - endSame);
+ pdoc->InsertString(currentNoVS.Start().Position() + firstDifference,
+ sMapped.c_str() + firstDifference, lastDifference - firstDifference + 1);
+ // Automatic movement changes selection so reset to exactly the same as it was.
+ sel.Range(r) = current;
+ }
+ }
+ delete []text;
}
}
@@ -4531,7 +4874,6 @@ void Editor::Duplicate(bool forLine) {
forLine = true;
}
UndoGroup ug(pdoc, sel.Count() > 1);
- SelectionPosition last;
const char *eol = "";
int eolLen = 0;
if (forLine) {
@@ -4613,10 +4955,10 @@ void Editor::CursorUpOrDown(int direction, Selection::selTypes selt) {
int subLine = (pt.y - ptStartLine.y) / vs.lineHeight;
int commentLines = vs.annotationVisible ? pdoc->AnnotationLines(lineDoc) : 0;
SelectionPosition posNew = SPositionFromLocation(
- Point(lastXChosen, pt.y + direction * vs.lineHeight), false, false, UserVirtualSpace());
+ Point(lastXChosen - xOffset, pt.y + direction * vs.lineHeight), false, false, UserVirtualSpace());
if ((direction > 0) && (subLine >= (cs.GetHeight(lineDoc) - 1 - commentLines))) {
posNew = SPositionFromLocation(
- Point(lastXChosen, pt.y + (commentLines + 1) * vs.lineHeight), false, false, UserVirtualSpace());
+ Point(lastXChosen - xOffset, pt.y + (commentLines + 1) * vs.lineHeight), false, false, UserVirtualSpace());
}
if (direction < 0) {
// Line wrapping may lead to a location on the same line, so
@@ -4935,6 +5277,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
inOverstrike = !inOverstrike;
DropCaret();
ShowCaretAtCurrentPosition();
+ ContainerNeedsUpdate(SC_UPDATE_CONTENT);
NotifyUpdateUI();
break;
case SCI_CANCEL: // Cancel any modes - handled in subclass
@@ -4943,21 +5286,21 @@ int Editor::KeyCommand(unsigned int iMessage) {
break;
case SCI_DELETEBACK:
DelCharBack(true);
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
SetLastXChosen();
}
EnsureCaretVisible();
break;
case SCI_DELETEBACKNOTLINE:
DelCharBack(false);
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
SetLastXChosen();
}
EnsureCaretVisible();
break;
case SCI_TAB:
Indent(true);
- if (!caretSticky) {
+ if (caretSticky == SC_CARETSTICKY_OFF) {
SetLastXChosen();
}
EnsureCaretVisible();
@@ -4965,7 +5308,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
break;
case SCI_BACKTAB:
Indent(false);
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
SetLastXChosen();
}
EnsureCaretVisible();
@@ -5034,6 +5377,7 @@ int Editor::KeyCommand(unsigned int iMessage) {
UndoGroup ug(pdoc);
sel.RangeMain().caret = SelectionPosition(
InsertSpace(sel.RangeMain().caret.Position(), sel.RangeMain().caret.VirtualSpace()));
+ sel.RangeMain().anchor = sel.RangeMain().caret;
int endWord = pdoc->NextWordStart(sel.MainCaret(), 1);
pdoc->DeleteChars(sel.MainCaret(), endWord - sel.MainCaret());
}
@@ -5094,10 +5438,10 @@ int Editor::KeyCommand(unsigned int iMessage) {
Duplicate(false);
break;
case SCI_LOWERCASE:
- ChangeCaseOfSelection(false);
+ ChangeCaseOfSelection(cmLower);
break;
case SCI_UPPERCASE:
- ChangeCaseOfSelection(true);
+ ChangeCaseOfSelection(cmUpper);
break;
case SCI_WORDPARTLEFT:
MovePositionTo(MovePositionSoVisible(pdoc->WordPartLeft(sel.MainCaret()), -1));
@@ -5205,7 +5549,7 @@ void Editor::Indent(bool forwards) {
int indentation = pdoc->GetLineIndentation(lineCurrentPos);
int indentationStep = pdoc->IndentSize();
pdoc->SetLineIndentation(lineCurrentPos, indentation - indentationStep);
- SetEmptySelection(pdoc->GetLineIndentPosition(lineCurrentPos));
+ sel.Range(r) = SelectionRange(pdoc->GetLineIndentPosition(lineCurrentPos));
} else {
int newColumn = ((pdoc->GetColumn(caretPosition) - 1) / pdoc->tabInChars) *
pdoc->tabInChars;
@@ -5244,6 +5588,31 @@ void Editor::Indent(bool forwards) {
}
}
+class CaseFolderASCII : public CaseFolderTable {
+public:
+ CaseFolderASCII() {
+ StandardASCII();
+ }
+ ~CaseFolderASCII() {
+ }
+ virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
+ if (lenMixed > sizeFolded) {
+ return 0;
+ } else {
+ for (size_t i=0; i<lenMixed; i++) {
+ folded[i] = mapping[static_cast<unsigned char>(mixed[i])];
+ }
+ return lenMixed;
+ }
+ }
+};
+
+
+CaseFolder *Editor::CaseFolderForEncoding() {
+ // Simple default that only maps ASCII upper case to lower case.
+ return new CaseFolderASCII();
+}
+
/**
* Search of a text in the document, in the given range.
* @return The position of the found text, -1 if not found.
@@ -5255,13 +5624,15 @@ long Editor::FindText(
Sci_TextToFind *ft = reinterpret_cast<Sci_TextToFind *>(lParam);
int lengthFound = istrlen(ft->lpstrText);
+ std::auto_ptr<CaseFolder> pcf(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);
+ &lengthFound,
+ pcf.get());
if (pos != -1) {
ft->chrgText.cpMin = pos;
ft->chrgText.cpMax = pos + lengthFound;
@@ -5298,6 +5669,7 @@ long Editor::SearchText(
const char *txt = reinterpret_cast<char *>(lParam);
int pos;
int lengthFound = istrlen(txt);
+ std::auto_ptr<CaseFolder> pcf(CaseFolderForEncoding());
if (iMessage == SCI_SEARCHNEXT) {
pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt,
(wParam & SCFIND_MATCHCASE) != 0,
@@ -5305,7 +5677,8 @@ long Editor::SearchText(
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound);
+ &lengthFound,
+ pcf.get());
} else {
pos = pdoc->FindText(searchAnchor, 0, txt,
(wParam & SCFIND_MATCHCASE) != 0,
@@ -5313,9 +5686,9 @@ long Editor::SearchText(
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound);
+ &lengthFound,
+ pcf.get());
}
-
if (pos != -1) {
SetSelection(pos, pos + lengthFound);
}
@@ -5323,19 +5696,39 @@ long Editor::SearchText(
return pos;
}
+std::string Editor::CaseMapString(const std::string &s, int caseMapping) {
+ std::string ret(s);
+ for (size_t i=0; i<ret.size(); i++) {
+ switch (caseMapping) {
+ case cmUpper:
+ if (ret[i] >= 'a' && ret[i] <= 'z')
+ ret[i] = static_cast<char>(ret[i] - 'a' + 'A');
+ break;
+ case cmLower:
+ if (ret[i] >= 'A' && ret[i] <= 'Z')
+ ret[i] = static_cast<char>(ret[i] - 'A' + 'a');
+ break;
+ }
+ }
+ return ret;
+}
+
/**
* Search for text in the target range of the document.
* @return The position of the found text, -1 if not found.
*/
long Editor::SearchInTarget(const char *text, int length) {
int lengthFound = length;
+
+ std::auto_ptr<CaseFolder> pcf(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);
+ &lengthFound,
+ pcf.get());
if (pos != -1) {
targetStart = pos;
targetEnd = pos + lengthFound;
@@ -5591,6 +5984,16 @@ bool Editor::PointInSelMargin(Point pt) {
}
}
+Window::Cursor Editor::GetMarginCursor(Point pt) {
+ int x = 0;
+ for (int margin = 0; margin < ViewStyle::margins; 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;
+ }
+ return Window::cursorReverseArrow;
+}
+
void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
if (lineAnchor_ < lineCurrent_) {
SetSelection(pdoc->LineStart(lineCurrent_ + 1),
@@ -5604,6 +6007,30 @@ void Editor::LineSelection(int lineCurrent_, int lineAnchor_) {
}
}
+void Editor::WordSelection(int pos) {
+ if (pos < wordSelectAnchorStartPos) {
+ // Extend backward to the word containing pos.
+ // Skip ExtendWordSelect if the line is empty or if pos is after the last character.
+ // This ensures that a series of empty lines isn't counted as a single "word".
+ if (!pdoc->IsLineEndPosition(pos))
+ pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos + 1, 1), -1);
+ SetSelection(pos, wordSelectAnchorEndPos);
+ } else if (pos > wordSelectAnchorEndPos) {
+ // Extend forward to the word containing the character to the left of pos.
+ // Skip ExtendWordSelect if the line is empty or if pos is the first position on the line.
+ // This ensures that a series of empty lines isn't counted as a single "word".
+ if (pos > pdoc->LineStart(pdoc->LineFromPosition(pos)))
+ pos = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(pos - 1, -1), 1);
+ SetSelection(pos, wordSelectAnchorStartPos);
+ } else {
+ // Select only the anchored word
+ if (pos >= originalAnchorPos)
+ SetSelection(wordSelectAnchorEndPos, wordSelectAnchorStartPos);
+ else
+ SetSelection(wordSelectAnchorStartPos, wordSelectAnchorEndPos);
+ }
+}
+
void Editor::DwellEnd(bool mouseMoved) {
if (mouseMoved)
ticksToDwell = dwellDelay;
@@ -5615,7 +6042,15 @@ void Editor::DwellEnd(bool mouseMoved) {
}
}
-static bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) {
+void Editor::MouseLeave() {
+ SetHotSpotRange(NULL);
+ if (!HaveMouseCapture()) {
+ ptMouseLast = Point(-1,-1);
+ DwellEnd(true);
+ }
+}
+
+static bool AllowVirtualSpace(int virtualSpaceOptions, bool rectangular) {
return ((virtualSpaceOptions & SCVS_USERACCESSIBLE) != 0)
|| (rectangular && ((virtualSpaceOptions & SCVS_RECTANGULARSELECTION) != 0));
}
@@ -5657,13 +6092,33 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
}
if (selectionType == selWord) {
- if (sel.MainCaret() >= originalAnchorPos) { // Moved forward
- SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), 1),
- pdoc->ExtendWordSelect(originalAnchorPos, -1));
- } else { // Moved backward
- SetSelection(pdoc->ExtendWordSelect(sel.MainCaret(), -1),
- pdoc->ExtendWordSelect(originalAnchorPos, 1));
+ int charPos = originalAnchorPos;
+ if (sel.MainCaret() == originalAnchorPos) {
+ charPos = PositionFromLocation(pt, false, true);
+ charPos = MovePositionOutsideChar(charPos, -1);
+ }
+
+ int startWord, endWord;
+ if ((sel.MainCaret() >= originalAnchorPos) && !pdoc->IsLineEndPosition(charPos)) {
+ startWord = pdoc->ExtendWordSelect(pdoc->MovePositionOutsideChar(charPos + 1, 1), -1);
+ endWord = pdoc->ExtendWordSelect(charPos, 1);
+ } else {
+ // Selecting backwards, or anchor beyond last character on line. In these cases,
+ // we select the word containing the character to the *left* of the anchor.
+ if (charPos > pdoc->LineStart(pdoc->LineFromPosition(charPos))) {
+ startWord = pdoc->ExtendWordSelect(charPos, -1);
+ endWord = pdoc->ExtendWordSelect(startWord, 1);
+ } else {
+ // Anchor at start of line; select nothing to begin with.
+ startWord = charPos;
+ endWord = charPos;
+ }
}
+
+ wordSelectAnchorStartPos = startWord;
+ wordSelectAnchorEndPos = endWord;
+ wordSelectInitialCaretPos = sel.MainCaret();
+ WordSelection(wordSelectInitialCaretPos);
} else if (selectionType == selLine) {
lineAnchor = LineFromLocation(pt);
SetSelection(pdoc->LineStart(lineAnchor + 1), pdoc->LineStart(lineAnchor));
@@ -5708,6 +6163,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
} else {
if (PointIsHotspot(pt)) {
NotifyHotSpotClicked(newPos.Position(), shift, ctrl, alt);
+ hotSpotClickPos = PositionFromLocation(pt,true,false);
}
if (!shift) {
if (PointInSelection(pt) && !SelectionEmpty())
@@ -5727,7 +6183,8 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
InvalidateSelection(SelectionRange(newPos), true);
if (sel.Count() > 1)
Redraw();
- sel.Clear();
+ if ((sel.Count() > 1) || (sel.selType != Selection::selStream))
+ sel.Clear();
sel.selType = alt ? Selection::selRectangle : Selection::selStream;
SetSelection(newPos, newPos);
}
@@ -5745,7 +6202,7 @@ void Editor::ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, b
}
}
lastClickTime = curTime;
- lastXChosen = pt.x;
+ lastXChosen = pt.x + xOffset;
ShowCaretAtCurrentPosition();
}
@@ -5793,7 +6250,7 @@ void Editor::SetHotSpotRange(Point *pt) {
}
}
-void Editor::GetHotSpotRange(int& hsStart_, int& hsEnd_) {
+void Editor::GetHotSpotRange(int &hsStart_, int &hsEnd_) {
hsStart_ = hsStart;
hsEnd_ = hsEnd;
}
@@ -5844,7 +6301,7 @@ void Editor::ButtonMove(Point pt) {
}
} else if (selectionType == selWord) {
// Continue selecting by word
- if (movePos.Position() == originalAnchorPos) { // Didn't move
+ if (movePos.Position() == wordSelectInitialCaretPos) { // Didn't move
// No need to do anything. Previously this case was lumped
// in with "Moved forward", but that can be harmful in this
// case: a handler for the NotifyDoubleClick re-adjusts
@@ -5854,12 +6311,9 @@ void Editor::ButtonMove(Point pt) {
// the ButtonMove() called via Tick() for auto-scrolling
// could result in the fancier word selection adjustment
// being unmade.
- } else if (movePos.Position() > originalAnchorPos) { // Moved forward
- SetSelection(pdoc->ExtendWordSelect(movePos.Position(), 1),
- pdoc->ExtendWordSelect(originalAnchorPos, -1));
- } else { // Moved backward
- SetSelection(pdoc->ExtendWordSelect(movePos.Position(), -1),
- pdoc->ExtendWordSelect(originalAnchorPos, 1));
+ } else {
+ wordSelectInitialCaretPos = -1;
+ WordSelection(movePos.Position());
}
} else {
// Continue selecting by line
@@ -5887,10 +6341,18 @@ void Editor::ButtonMove(Point pt) {
if (hsStart != -1 && !PositionIsHotspot(movePos.Position()))
SetHotSpotRange(NULL);
+ if (hotSpotClickPos != INVALID_POSITION && PositionFromLocation(pt,true,false) != hotSpotClickPos) {
+ if (inDragDrop == ddNone) {
+ DisplayCursor(Window::cursorText);
+ }
+ hotSpotClickPos = INVALID_POSITION;
+ }
+
} else {
if (vs.fixedColumnWidth > 0) { // There is a margin
if (PointInSelMargin(pt)) {
- DisplayCursor(Window::cursorReverseArrow);
+ DisplayCursor(GetMarginCursor(pt));
+ SetHotSpotRange(NULL);
return; // No need to test for selection
}
}
@@ -5915,10 +6377,16 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
if (inDragDrop == ddInitial) {
inDragDrop = ddNone;
SetEmptySelection(newPos.Position());
+ selectionType = selChar;
+ originalAnchorPos = sel.MainCaret();
+ }
+ if (hotSpotClickPos != INVALID_POSITION && PointIsHotspot(pt)) {
+ hotSpotClickPos = INVALID_POSITION;
+ NotifyHotSpotReleaseClick(newPos.Position(), false, ctrl, false);
}
if (HaveMouseCapture()) {
if (PointInSelMargin(pt)) {
- DisplayCursor(Window::cursorReverseArrow);
+ DisplayCursor(GetMarginCursor(pt));
} else {
DisplayCursor(Window::cursorText);
SetHotSpotRange(NULL);
@@ -5968,7 +6436,7 @@ void Editor::ButtonUp(Point pt, unsigned int curTime, bool ctrl) {
SetRectangularRange();
lastClickTime = curTime;
lastClick = pt;
- lastXChosen = pt.x;
+ lastXChosen = pt.x + xOffset;
if (sel.selType == Selection::selStream) {
SetLastXChosen();
}
@@ -6000,7 +6468,8 @@ void Editor::Tick() {
}
if ((dwellDelay < SC_TIME_FOREVER) &&
(ticksToDwell > 0) &&
- (!HaveMouseCapture())) {
+ (!HaveMouseCapture()) &&
+ (ptMouseLast.y >= 0)) {
ticksToDwell -= timer.tickSize;
if (ticksToDwell <= 0) {
dwelling = true;
@@ -6044,6 +6513,48 @@ void Editor::SetFocusState(bool focusState) {
}
}
+int Editor::PositionAfterArea(PRectangle rcArea) {
+ // The start of the document line after the display line after the area
+ // This often means that the line after a modification is restyled which helps
+ // detect multiline comment additions and heals single line comments
+ int lineAfter = topLine + (rcArea.bottom - 1) / vs.lineHeight + 1;
+ if (lineAfter < cs.LinesDisplayed())
+ return pdoc->LineStart(cs.DocFromDisplay(lineAfter) + 1);
+ else
+ return pdoc->Length();
+}
+
+// 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());
+ if (pos > endWindow)
+ pos = endWindow;
+ int styleAtEnd = pdoc->StyleAt(pos-1);
+ pdoc->EnsureStyledTo(pos);
+ if ((endWindow > pos) && (styleAtEnd != pdoc->StyleAt(pos-1))) {
+ // Style at end of line changed so is multi-line change like starting a comment
+ // so require rest of window to be styled.
+ pdoc->EnsureStyledTo(endWindow);
+ }
+}
+
+void Editor::IdleStyling() {
+ // 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 (needUpdateUI) {
+ NotifyUpdateUI();
+ needUpdateUI = 0;
+ }
+ styleNeeded.Reset();
+}
+
+void Editor::QueueStyling(int upTo) {
+ styleNeeded.NeedUpTo(upTo);
+}
+
bool Editor::PaintContains(PRectangle rc) {
if (rc.Empty()) {
return true;
@@ -6150,6 +6661,7 @@ void Editor::SetAnnotationVisible(int visible) {
}
}
}
+ Redraw();
}
}
@@ -6185,8 +6697,8 @@ void Editor::ToggleContraction(int line) {
if (cs.GetExpanded(line)) {
int lineMaxSubord = pdoc->GetLastChild(line);
- cs.SetExpanded(line, 0);
if (lineMaxSubord > line) {
+ cs.SetExpanded(line, 0);
cs.SetVisible(line + 1, lineMaxSubord, false);
int lineCurrent = pdoc->LineFromPosition(sel.MainCaret());
@@ -6212,6 +6724,18 @@ void Editor::ToggleContraction(int line) {
}
}
+int Editor::ContractedFoldNext(int lineStart) {
+ for (int line = lineStart; line<pdoc->LinesTotal();) {
+ if (!cs.GetExpanded(line) && (pdoc->GetLevel(line) & SC_FOLDLEVELHEADERFLAG))
+ return line;
+ line = cs.ContractedNext(line+1);
+ if (line < 0)
+ return -1;
+ }
+
+ return -1;
+}
+
/**
* Recurse up from this line to find any folds that prevent this line from being visible
* and unfold them all.
@@ -6257,6 +6781,24 @@ 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)) {
+ name[1] = static_cast<char>(tagNumber + '0');
+ length = 2;
+ text = pdoc->SubstituteByPosition(name, &length);
+ }
+ if (tagValue) {
+ if (text)
+ memcpy(tagValue, text, length + 1);
+ else
+ *tagValue = '\0';
+ }
+ return length;
+}
+
int Editor::ReplaceTarget(bool replacePatterns, const char *text, int length) {
UndoGroup ug(pdoc);
if (length == -1)
@@ -6303,11 +6845,11 @@ void Editor::AddStyledText(char *buffer, int appendLength) {
size_t textLength = appendLength / 2;
char *text = new char[textLength];
size_t i;
- for (i = 0;i < textLength;i++) {
+ for (i = 0; i < textLength; i++) {
text[i] = buffer[i*2];
}
pdoc->InsertString(CurrentPosition(), text, textLength);
- for (i = 0;i < textLength;i++) {
+ for (i = 0; i < textLength; i++) {
text[i] = buffer[i*2+1];
}
pdoc->StartStyling(CurrentPosition(), static_cast<char>(0xff));
@@ -6466,6 +7008,18 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
CopyAllowLine();
break;
+ case SCI_VERTICALCENTRECARET:
+ VerticalCentreCaret();
+ break;
+
+ case SCI_MOVESELECTEDLINESUP:
+ MoveSelectedLinesUp();
+ break;
+
+ case SCI_MOVESELECTEDLINESDOWN:
+ MoveSelectedLinesDown();
+ break;
+
case SCI_COPYRANGE:
CopyRangeToClipboard(wParam, lParam);
break;
@@ -6476,7 +7030,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_PASTE:
Paste();
- if (!caretSticky) {
+ if ((caretSticky == SC_CARETSTICKY_OFF) || (caretSticky == SC_CARETSTICKY_WHITESPACE)) {
SetLastXChosen();
}
EnsureCaretVisible();
@@ -6641,6 +7195,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_GETSEARCHFLAGS:
return searchFlags;
+ case SCI_GETTAG:
+ return GetTag(CharPtrFromSPtr(lParam), wParam);
+
case SCI_POSITIONBEFORE:
return pdoc->MovePositionOutsideChar(wParam - 1, -1, true);
@@ -6654,6 +7211,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETXOFFSET:
xOffset = wParam;
+ ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
SetHorizontalScrollPos();
Redraw();
break;
@@ -6861,14 +7419,14 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
break;
case SCI_GETSELECTIONSTART:
- return Platform::Minimum(sel.MainAnchor(), sel.MainCaret());
+ return sel.LimitsForRectangularElseMain().start.Position();
case SCI_SETSELECTIONEND:
SetSelection(wParam, Platform::Minimum(sel.MainAnchor(), wParam));
break;
case SCI_GETSELECTIONEND:
- return Platform::Maximum(sel.MainAnchor(), sel.MainCaret());
+ return sel.LimitsForRectangularElseMain().end.Position();
case SCI_SETPRINTMAGNIFICATION:
printMagnification = wParam;
@@ -6968,7 +7526,6 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_GOTOPOS:
SetEmptySelection(wParam);
EnsureCaretVisible();
- Redraw();
break;
case SCI_GETCURLINE: {
@@ -7119,6 +7676,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
break;
}
xOffset = 0;
+ ContainerNeedsUpdate(SC_UPDATE_H_SCROLL);
InvalidateStyleRedraw();
ReconfigureScrollBars();
break;
@@ -7127,9 +7685,11 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return wrapState;
case SCI_SETWRAPVISUALFLAGS:
- wrapVisualFlags = wParam;
- InvalidateStyleRedraw();
- ReconfigureScrollBars();
+ if (wrapVisualFlags != static_cast<int>(wParam)) {
+ wrapVisualFlags = wParam;
+ InvalidateStyleRedraw();
+ ReconfigureScrollBars();
+ }
break;
case SCI_GETWRAPVISUALFLAGS:
@@ -7144,18 +7704,22 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return wrapVisualFlagsLocation;
case SCI_SETWRAPSTARTINDENT:
- wrapVisualStartIndent = wParam;
- InvalidateStyleRedraw();
- ReconfigureScrollBars();
+ if (wrapVisualStartIndent != static_cast<int>(wParam)) {
+ wrapVisualStartIndent = wParam;
+ InvalidateStyleRedraw();
+ ReconfigureScrollBars();
+ }
break;
case SCI_GETWRAPSTARTINDENT:
return wrapVisualStartIndent;
case SCI_SETWRAPINDENTMODE:
- wrapIndentMode = wParam;
- InvalidateStyleRedraw();
- ReconfigureScrollBars();
+ if (wrapIndentMode != static_cast<int>(wParam)) {
+ wrapIndentMode = wParam;
+ InvalidateStyleRedraw();
+ ReconfigureScrollBars();
+ }
break;
case SCI_GETWRAPINDENTMODE:
@@ -7222,9 +7786,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return endAtLastLine;
case SCI_SETCARETSTICKY:
- PLATFORM_ASSERT((wParam == 0) || (wParam == 1));
- if (caretSticky != (wParam != 0)) {
- caretSticky = wParam != 0;
+ PLATFORM_ASSERT((wParam >= SC_CARETSTICKY_OFF) && (wParam <= SC_CARETSTICKY_WHITESPACE));
+ if ((wParam >= SC_CARETSTICKY_OFF) && (wParam <= SC_CARETSTICKY_WHITESPACE)) {
+ caretSticky = wParam;
}
break;
@@ -7322,6 +7886,15 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
InvalidateStyleData();
RedrawSelMargin();
break;
+ case SCI_MARKERSETBACKSELECTED:
+ if (wParam <= MARKER_MAX)
+ vs.markers[wParam].backSelected.desired = ColourDesired(lParam);
+ InvalidateStyleRedraw();
+ break;
+ case SCI_MARKERENABLEHIGHLIGHT:
+ highlightDelimiter.isEnabled = wParam == 1;
+ InvalidateStyleRedraw();
+ break;
case SCI_MARKERSETBACK:
if (wParam <= MARKER_MAX)
vs.markers[wParam].back.desired = ColourDesired(lParam);
@@ -7433,6 +8006,17 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
else
return 0;
+ case SCI_SETMARGINCURSORN:
+ if (ValidMargin(wParam))
+ vs.ms[wParam].cursor = lParam;
+ break;
+
+ case SCI_GETMARGINCURSORN:
+ if (ValidMargin(wParam))
+ return vs.ms[wParam].cursor;
+ else
+ return 0;
+
case SCI_STYLECLEARALL:
vs.ClearStyles();
InvalidateStyleRedraw();
@@ -7570,6 +8154,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
ToggleContraction(wParam);
break;
+ case SCI_CONTRACTEDFOLDNEXT:
+ return ContractedFoldNext(wParam);
+
case SCI_ENSUREVISIBLE:
EnsureLineVisible(wParam, false);
break;
@@ -7725,7 +8312,7 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return (wParam <= INDIC_MAX) ? vs.indicators[wParam].under : 0;
case SCI_INDICSETALPHA:
- if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 100) {
+ if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) {
vs.indicators[wParam].fillAlpha = lParam;
InvalidateStyleRedraw();
}
@@ -7734,6 +8321,16 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_INDICGETALPHA:
return (wParam <= INDIC_MAX) ? vs.indicators[wParam].fillAlpha : 0;
+ case SCI_INDICSETOUTLINEALPHA:
+ if (wParam <= INDIC_MAX && lParam >=0 && lParam <= 255) {
+ vs.indicators[wParam].outlineAlpha = lParam;
+ InvalidateStyleRedraw();
+ }
+ break;
+
+ case SCI_INDICGETOUTLINEALPHA:
+ return (wParam <= INDIC_MAX) ? vs.indicators[wParam].outlineAlpha : 0;
+
case SCI_SETINDICATORCURRENT:
pdoc->decorations.SetCurrentIndicator(wParam);
break;
@@ -7859,10 +8456,24 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
SetBraceHighlight(static_cast<int>(wParam), lParam, STYLE_BRACELIGHT);
break;
+ case SCI_BRACEHIGHLIGHTINDICATOR:
+ if (lParam >= 0 && lParam <= INDIC_MAX) {
+ vs.braceHighlightIndicatorSet = wParam != 0;
+ vs.braceHighlightIndicator = lParam;
+ }
+ break;
+
case SCI_BRACEBADLIGHT:
SetBraceHighlight(static_cast<int>(wParam), -1, STYLE_BRACEBAD);
break;
+ case SCI_BRACEBADLIGHTINDICATOR:
+ if (lParam >= 0 && lParam <= INDIC_MAX) {
+ vs.braceBadLightIndicatorSet = wParam != 0;
+ vs.braceBadLightIndicator = lParam;
+ }
+ break;
+
case SCI_BRACEMATCH:
// wParam is position of char to find brace for,
// lParam is maximum amount of text to restyle to find it
@@ -8261,6 +8872,13 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_GETADDITIONALSELECTIONTYPING:
return additionalSelectionTyping;
+ case SCI_SETMULTIPASTE:
+ multiPasteMode = wParam;
+ break;
+
+ case SCI_GETMULTIPASTE:
+ return multiPasteMode;
+
case SCI_SETADDITIONALCARETSBLINK:
additionalCaretsBlink = wParam != 0;
InvalidateCaret();
@@ -8441,6 +9059,10 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
sel.RangeMain() = SelectionRange(sel.RangeMain().anchor, sel.RangeMain().caret);
break;
+ case SCI_CHANGELEXERSTATE:
+ pdoc->ChangeLexerState(wParam, lParam);
+ break;
+
default:
return DefWndProc(iMessage, wParam, lParam);
}
diff --git a/plugins/scintilla/scintilla/Editor.h b/plugins/scintilla/scintilla/Editor.h
index 92dcfb1..5c01ee8 100644
--- a/plugins/scintilla/scintilla/Editor.h
+++ b/plugins/scintilla/scintilla/Editor.h
@@ -2,7 +2,7 @@
/** @file Editor.h
** Defines the main editor class.
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef EDITOR_H
@@ -46,6 +46,26 @@ public:
};
/**
+ * When platform has a way to generate an event before painting,
+ * accumulate needed styling range in StyleNeeded to avoid unnecessary work.
+ */
+class StyleNeeded {
+public:
+ bool active;
+ Position upTo;
+
+ StyleNeeded() : active(false), upTo(0) {}
+ void Reset() {
+ active = false;
+ upTo = 0;
+ }
+ void NeedUpTo(Position pos) {
+ if (upTo < pos)
+ upTo = pos;
+ }
+};
+
+/**
* Hold a piece of text selected for copying or dragging.
* The text is expected to hold a terminating '\0' and this is counted in len.
*/
@@ -119,6 +139,9 @@ protected: // ScintillaBase subclass needs access to much of Editor
int cursorMode;
int controlCharSymbol;
+ // Highlight current folding block
+ HighlightDelimiter highlightDelimiter;
+
bool hasFocus;
bool hideSelection;
bool inOverstrike;
@@ -139,9 +162,10 @@ protected: // ScintillaBase subclass needs access to much of Editor
int lineWidthMaxSeen;
bool verticalScrollBarVisible;
bool endAtLastLine;
- bool caretSticky;
+ int caretSticky;
bool multipleSelection;
bool additionalSelectionTyping;
+ int multiPasteMode;
bool additionalCaretsBlink;
bool additionalCaretsVisible;
@@ -176,9 +200,13 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool dropWentOutside;
SelectionPosition posDrag;
SelectionPosition posDrop;
+ int hotSpotClickPos;
int lastXChosen;
int lineAnchor;
int originalAnchorPos;
+ int wordSelectAnchorStartPos;
+ int wordSelectAnchorEndPos;
+ int wordSelectInitialCaretPos;
int targetStart;
int targetEnd;
int searchFlags;
@@ -186,7 +214,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
int posTopLine;
int lengthForEncode;
- bool needUpdateUI;
+ int needUpdateUI;
Position braces[2];
int bracesMatchStyle;
int highlightGuideColumn;
@@ -196,6 +224,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
enum { notPainting, painting, paintAbandoned } paintState;
PRectangle rcPaint;
bool paintingAllText;
+ StyleNeeded styleNeeded;
int modEventMask;
@@ -271,7 +300,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool AbandonPaint();
void RedrawRect(PRectangle rc);
void Redraw();
- void RedrawSelMargin(int line=-1);
+ void RedrawSelMargin(int line=-1, bool allAfter=false);
PRectangle RectangleFromRange(int start, int end);
void InvalidateRange(int start, int end);
@@ -305,8 +334,20 @@ protected: // ScintillaBase subclass needs access to much of Editor
void ScrollTo(int line, bool moveThumb=true);
virtual void ScrollText(int linesToMove);
void HorizontalScrollTo(int xPos);
+ void VerticalCentreCaret();
+ void MoveSelectedLines(int lineDelta);
+ void MoveSelectedLinesUp();
+ void MoveSelectedLinesDown();
void MoveCaretInsideView(bool ensureVisible=true);
int DisplayFromPosition(int pos);
+
+ struct XYScrollPosition {
+ int xOffset;
+ int topLine;
+ XYScrollPosition(int xOffset_, int topLine_) : xOffset(xOffset_), topLine(topLine_) {}
+ };
+ XYScrollPosition XYScrollToMakeVisible(const bool useMargin, const bool vert, const bool horiz);
+ void SetXYScroll(XYScrollPosition newXY);
void EnsureCaretVisible(bool useMargin=true, bool vert=true, bool horiz=true);
void ShowCaretAtCurrentPosition();
void DropCaret();
@@ -332,13 +373,15 @@ protected: // ScintillaBase subclass needs access to much of Editor
int line, int lineEnd, int xStart, int subLine, int subLineStart,
bool overrideBackground, ColourAllocated background,
bool drawWrapMark, ColourAllocated wrapColour);
+ void DrawIndicator(int indicNum, int startPos, int endPos, Surface *surface, ViewStyle &vsDraw,
+ int xStart, PRectangle rcLine, LineLayout *ll, int subLine);
void DrawIndicators(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine, int lineEnd, bool under);
void DrawAnnotation(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
void DrawLine(Surface *surface, ViewStyle &vsDraw, int line, int lineVisible, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
- void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine,
+ void DrawBlockCaret(Surface *surface, ViewStyle &vsDraw, LineLayout *ll, int subLine,
int xStart, int offset, int posCaret, PRectangle rcCaret, ColourAllocated caretColour);
void DrawCarets(Surface *surface, ViewStyle &vsDraw, int line, int xStart,
PRectangle rcLine, LineLayout *ll, int subLine);
@@ -358,7 +401,8 @@ protected: // ScintillaBase subclass needs access to much of Editor
int InsertSpace(int position, unsigned int spaces);
void AddChar(char ch);
virtual void AddCharUTF(char *s, unsigned int len, bool treatAsDBCS=false);
- void ClearSelection();
+ void InsertPaste(SelectionPosition selStart, const char *text, int len);
+ void ClearSelection(bool retainMultipleSelections=false);
void ClearAll();
void ClearDocumentStyle();
void Cut();
@@ -386,6 +430,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual void NotifyDoubleClick(Point pt, bool shift, bool ctrl, bool alt);
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();
void NotifyPainted();
void NotifyIndicatorClick(bool click, int position, bool shift, bool ctrl, bool alt);
@@ -400,10 +445,15 @@ protected: // ScintillaBase subclass needs access to much of Editor
void NotifyModified(Document *document, DocModification mh, void *userData);
void NotifyDeleted(Document *document, void *userData);
void NotifyStyleNeeded(Document *doc, void *userData, int endPos);
+ void NotifyLexerChanged(Document *doc, void *userData);
+ void NotifyErrorOccurred(Document *doc, void *userData, int status);
void NotifyMacroRecord(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
+ void ContainerNeedsUpdate(int flags);
void PageMove(int direction, Selection::selTypes sel=Selection::noSel, bool stuttered = false);
- void ChangeCaseOfSelection(bool makeUpperCase);
+ enum { cmSame, cmUpper, cmLower } caseMap;
+ virtual std::string CaseMapString(const std::string &s, int caseMapping);
+ void ChangeCaseOfSelection(int caseMapping);
void LineTranspose();
void Duplicate(bool forLine);
virtual void CancelModes();
@@ -420,6 +470,7 @@ protected: // ScintillaBase subclass needs access to much of Editor
void Indent(bool forwards);
+ virtual CaseFolder *CaseFolderForEncoding();
long FindText(uptr_t wParam, sptr_t lParam);
void SearchAnchor();
long SearchText(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
@@ -440,8 +491,11 @@ protected: // ScintillaBase subclass needs access to much of Editor
bool PositionInSelection(int pos);
bool PointInSelection(Point pt);
bool PointInSelMargin(Point pt);
+ Window::Cursor GetMarginCursor(Point pt);
void LineSelection(int lineCurrent_, int lineAnchor_);
+ void WordSelection(int pos);
void DwellEnd(bool mouseMoved);
+ void MouseLeave();
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
void ButtonMove(Point pt);
void ButtonUp(Point pt, unsigned int curTime, bool ctrl);
@@ -454,6 +508,11 @@ protected: // ScintillaBase subclass needs access to much of Editor
virtual bool HaveMouseCapture() = 0;
void SetFocusState(bool focusState);
+ int PositionAfterArea(PRectangle rcArea);
+ void StyleToPositionInView(Position pos);
+ void IdleStyling();
+ virtual void QueueStyling(int upTo);
+
virtual bool PaintContains(PRectangle rc);
bool PaintContainsMargin();
void CheckForChangeOutsidePaint(Range r);
@@ -461,18 +520,20 @@ protected: // ScintillaBase subclass needs access to much of Editor
void SetAnnotationHeights(int start, int end);
void SetDocPointer(Document *document);
-
+
void SetAnnotationVisible(int visible);
void Expand(int &line, bool doExpand);
void ToggleContraction(int line);
+ int ContractedFoldNext(int lineStart);
void EnsureLineVisible(int lineDoc, bool enforcePolicy);
+ int GetTag(char *tagValue, int tagNumber);
int ReplaceTarget(bool replacePatterns, const char *text, int length=-1);
bool PositionIsHotspot(int position);
bool PointIsHotspot(Point pt);
void SetHotSpotRange(Point *pt);
- void GetHotSpotRange(int& hsStart, int& hsEnd);
+ void GetHotSpotRange(int &hsStart, int &hsEnd);
int CodePage() const;
virtual bool ValidCodePage(int /* codePage */) const { return true; }
diff --git a/plugins/scintilla/scintilla/ExternalLexer.cxx b/plugins/scintilla/scintilla/ExternalLexer.cxx
index 098df4d..bb48464 100644
--- a/plugins/scintilla/scintilla/ExternalLexer.cxx
+++ b/plugins/scintilla/scintilla/ExternalLexer.cxx
@@ -9,18 +9,18 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
+#include <assert.h>
#include <string>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
-
#include "SciLexer.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "DocumentAccessor.h"
-#include "KeyWords.h"
+
+#include "LexerModule.h"
+#include "Catalogue.h"
#include "ExternalLexer.h"
#ifdef SCI_NAMESPACE
@@ -35,77 +35,9 @@ LexerManager *LexerManager::theInstance = NULL;
//
//------------------------------------------
-char **WordListsToStrings(WordList *val[]) {
- int dim = 0;
- while (val[dim])
- dim++;
- char **wls = new char * [dim + 1];
- for (int i = 0;i < dim;i++) {
- std::string words;
- words = "";
- for (int n = 0; n < val[i]->len; n++) {
- words += val[i]->words[n];
- if (n != val[i]->len - 1)
- words += " ";
- }
- wls[i] = new char[words.length() + 1];
- strcpy(wls[i], words.c_str());
- }
- wls[dim] = 0;
- return wls;
-}
-
-void DeleteWLStrings(char *strs[]) {
- int dim = 0;
- while (strs[dim]) {
- delete strs[dim];
- dim++;
- }
- delete [] strs;
-}
-
-void ExternalLexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const {
- if (!fneLexer)
- return ;
-
- char **kwds = WordListsToStrings(keywordlists);
- char *ps = styler.GetProperties();
-
- // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
- // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
- DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
- WindowID wID = da.GetWindow();
-
- fneLexer(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
-
- delete ps;
- DeleteWLStrings(kwds);
-}
-
-void ExternalLexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const {
- if (!fneFolder)
- return ;
-
- char **kwds = WordListsToStrings(keywordlists);
- char *ps = styler.GetProperties();
-
- // The accessor passed in is always a DocumentAccessor so this cast and the subsequent
- // access will work. Can not use the stricter dynamic_cast as that requires RTTI.
- DocumentAccessor &da = static_cast<DocumentAccessor &>(styler);
- WindowID wID = da.GetWindow();
-
- fneFolder(externalLanguage, startPos, lengthDoc, initStyle, kwds, wID, ps);
-
- delete ps;
- DeleteWLStrings(kwds);
-}
-
-void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index) {
- fneLexer = fLexer;
- fneFolder = fFolder;
- externalLanguage = index;
+void ExternalLexerModule::SetExternal(GetLexerFactoryFunction fFactory, int index) {
+ fneFactory = fFactory;
+ fnFactory = fFactory(index);
}
//------------------------------------------
@@ -114,7 +46,7 @@ void ExternalLexerModule::SetExternal(ExtLexerFunction fLexer, ExtFoldFunction f
//
//------------------------------------------
-LexerLibrary::LexerLibrary(const char* ModuleName) {
+LexerLibrary::LexerLibrary(const char *ModuleName) {
// Initialise some members...
first = NULL;
last = NULL;
@@ -132,8 +64,7 @@ LexerLibrary::LexerLibrary(const char* ModuleName) {
// Find functions in the DLL
GetLexerNameFn GetLexerName = (GetLexerNameFn)(sptr_t)lib->FindFunction("GetLexerName");
- ExtLexerFunction Lexer = (ExtLexerFunction)(sptr_t)lib->FindFunction("Lex");
- ExtFoldFunction Folder = (ExtFoldFunction)(sptr_t)lib->FindFunction("Fold");
+ GetLexerFactoryFunction fnFactory = (GetLexerFactoryFunction)(sptr_t)lib->FindFunction("GetLexerFactory");
// Assign a buffer for the lexer name.
char lexname[100];
@@ -144,6 +75,7 @@ LexerLibrary::LexerLibrary(const char* ModuleName) {
for (int i = 0; i < nl; i++) {
GetLexerName(i, lexname, 100);
lex = new ExternalLexerModule(SCLEX_AUTOMATIC, NULL, lexname, NULL);
+ Catalogue::AddLexerModule(lex);
// Create a LexerMinder so we don't leak the ExternalLexerModule...
lm = new LexerMinder;
@@ -158,8 +90,8 @@ LexerLibrary::LexerLibrary(const char* ModuleName) {
}
// The external lexer needs to know how to call into its DLL to
- // do its lexing and folding, we tell it here. Folder may be null.
- lex->SetExternal(Lexer, Folder, i);
+ // do its lexing and folding, we tell it here.
+ lex->SetExternal(fnFactory, i);
}
}
}
@@ -172,7 +104,6 @@ LexerLibrary::~LexerLibrary() {
}
void LexerLibrary::Release() {
- //TODO maintain a list of lexers created, and delete them!
LexerMinder *lm;
LexerMinder *lmNext;
lm = first;
@@ -195,18 +126,15 @@ void LexerLibrary::Release() {
/// Return the single LexerManager instance...
LexerManager *LexerManager::GetInstance() {
- if(!theInstance)
+ if (!theInstance)
theInstance = new LexerManager;
return theInstance;
}
/// Delete any LexerManager instance...
-void LexerManager::DeleteInstance()
-{
- if(theInstance) {
- delete theInstance;
- theInstance = NULL;
- }
+void LexerManager::DeleteInstance() {
+ delete theInstance;
+ theInstance = NULL;
}
/// protected constructor - this is a singleton...
@@ -219,13 +147,15 @@ LexerManager::~LexerManager() {
Clear();
}
-void LexerManager::Load(const char* path)
-{
+void LexerManager::Load(const char *path) {
LoadLexerLibrary(path);
}
-void LexerManager::LoadLexerLibrary(const char* module)
-{
+void LexerManager::LoadLexerLibrary(const char *module) {
+ for (LexerLibrary *ll = first; ll; ll= ll->next) {
+ if (strcmp(ll->m_sModuleName.c_str(), module) == 0)
+ return;
+ }
LexerLibrary *lib = new LexerLibrary(module);
if (NULL != first) {
last->next = lib;
@@ -236,8 +166,7 @@ void LexerManager::LoadLexerLibrary(const char* module)
}
}
-void LexerManager::Clear()
-{
+void LexerManager::Clear() {
if (NULL != first) {
LexerLibrary *cur = first;
LexerLibrary *next;
@@ -257,8 +186,7 @@ void LexerManager::Clear()
//
//------------------------------------------
-LMMinder::~LMMinder()
-{
+LMMinder::~LMMinder() {
LexerManager::DeleteInstance();
}
diff --git a/plugins/scintilla/scintilla/ExternalLexer.h b/plugins/scintilla/scintilla/ExternalLexer.h
index 29f42cc..bf175a6 100644
--- a/plugins/scintilla/scintilla/ExternalLexer.h
+++ b/plugins/scintilla/scintilla/ExternalLexer.h
@@ -18,36 +18,26 @@
namespace Scintilla {
#endif
-// External Lexer function definitions...
-typedef void (EXT_LEXER_DECL *ExtLexerFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
- char *words[], WindowID window, char *props);
-typedef void (EXT_LEXER_DECL *ExtFoldFunction)(unsigned int lexer, unsigned int startPos, int length, int initStyle,
- char *words[], WindowID window, char *props);
-typedef void* (EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index);
+typedef void*(EXT_LEXER_DECL *GetLexerFunction)(unsigned int Index);
typedef int (EXT_LEXER_DECL *GetLexerCountFn)();
typedef void (EXT_LEXER_DECL *GetLexerNameFn)(unsigned int Index, char *name, int buflength);
-
-//class DynamicLibrary;
+typedef LexerFactoryFunction(EXT_LEXER_DECL *GetLexerFactoryFunction)(unsigned int Index);
/// Sub-class of LexerModule to use an external lexer.
-class ExternalLexerModule : protected LexerModule {
+class ExternalLexerModule : public LexerModule {
protected:
- ExtLexerFunction fneLexer;
- ExtFoldFunction fneFolder;
- int externalLanguage;
+ GetLexerFactoryFunction fneFactory;
char name[100];
public:
- ExternalLexerModule(int language_, LexerFunction fnLexer_,
- const char *languageName_=0, LexerFunction fnFolder_=0) : LexerModule(language_, fnLexer_, 0, fnFolder_){
+ ExternalLexerModule(int language_, LexerFunction fnLexer_,
+ const char *languageName_=0, LexerFunction fnFolder_=0) :
+ LexerModule(language_, fnLexer_, 0, fnFolder_),
+ fneFactory(0) {
strncpy(name, languageName_, sizeof(name));
name[sizeof(name)-1] = '\0';
languageName = name;
- };
- virtual void Lex(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const;
- virtual void Fold(unsigned int startPos, int lengthDoc, int initStyle,
- WordList *keywordlists[], Accessor &styler) const;
- virtual void SetExternal(ExtLexerFunction fLexer, ExtFoldFunction fFolder, int index);
+ }
+ virtual void SetExternal(GetLexerFactoryFunction fFactory, int index);
};
/// LexerMinder points to an ExternalLexerModule - so we don't leak them.
@@ -64,10 +54,10 @@ class LexerLibrary {
LexerMinder *last;
public:
- LexerLibrary(const char* ModuleName);
+ LexerLibrary(const char *ModuleName);
~LexerLibrary();
void Release();
-
+
LexerLibrary *next;
std::string m_sModuleName;
};
@@ -76,18 +66,18 @@ public:
class LexerManager {
public:
~LexerManager();
-
+
static LexerManager *GetInstance();
static void DeleteInstance();
-
- void Load(const char* path);
+
+ void Load(const char *path);
void Clear();
private:
LexerManager();
static LexerManager *theInstance;
- void LoadLexerLibrary(const char* module);
+ void LoadLexerLibrary(const char *module);
LexerLibrary *first;
LexerLibrary *last;
};
diff --git a/plugins/scintilla/scintilla/Indicator.cxx b/plugins/scintilla/scintilla/Indicator.cxx
index da95312..5c352bf 100644
--- a/plugins/scintilla/scintilla/Indicator.cxx
+++ b/plugins/scintilla/scintilla/Indicator.cxx
@@ -67,12 +67,12 @@ void Indicator::Draw(Surface *surface, const PRectangle &rc, const PRectangle &r
surface->LineTo(rc.right, rcLine.top+1);
surface->LineTo(rc.left, rcLine.top+1);
surface->LineTo(rc.left, ymid+1);
- } else if (style == INDIC_ROUNDBOX) {
+ } else if (style == INDIC_ROUNDBOX || style == INDIC_STRAIGHTBOX) {
PRectangle rcBox = rcLine;
rcBox.top = rcLine.top + 1;
rcBox.left = rc.left;
rcBox.right = rc.right;
- surface->AlphaRectangle(rcBox, 1, fore.allocated, fillAlpha, fore.allocated, 50, 0);
+ surface->AlphaRectangle(rcBox, (style == INDIC_ROUNDBOX) ? 1 : 0, fore.allocated, fillAlpha, fore.allocated, outlineAlpha, 0);
} else { // Either INDIC_PLAIN or unknown
surface->MoveTo(rc.left, ymid);
surface->LineTo(rc.right, ymid);
diff --git a/plugins/scintilla/scintilla/Indicator.h b/plugins/scintilla/scintilla/Indicator.h
index 42b56f0..e787b59 100644
--- a/plugins/scintilla/scintilla/Indicator.h
+++ b/plugins/scintilla/scintilla/Indicator.h
@@ -20,7 +20,8 @@ public:
bool under;
ColourPair fore;
int fillAlpha;
- Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30) {
+ int outlineAlpha;
+ Indicator() : style(INDIC_PLAIN), under(false), fore(ColourDesired(0,0,0)), fillAlpha(30), outlineAlpha(50) {
}
void Draw(Surface *surface, const PRectangle &rc, const PRectangle &rcLine);
};
diff --git a/plugins/scintilla/scintilla/LexA68k.cxx b/plugins/scintilla/scintilla/LexA68k.cxx
new file mode 100644
index 0000000..970e429
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexA68k.cxx
@@ -0,0 +1,318 @@
+// Scintilla source code edit control
+/** @file LexA68k.cxx
+ ** Lexer for Assembler, just for the MASM syntax
+ ** Written by Martial Demolins AKA Folco
+ **/
+// Copyright 2010 Martial Demolins <mdemolins(a)gmail.com>
+// The License.txt file describes the conditions under which this software
+// may be distributed.
+
+
+#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
+
+
+// Return values for GetOperatorType
+#define NO_OPERATOR 0
+#define OPERATOR_1CHAR 1
+#define OPERATOR_2CHAR 2
+
+
+/**
+ * IsIdentifierStart
+ *
+ * Return true if the given char is a valid identifier first char
+ */
+
+static inline bool IsIdentifierStart (const int ch)
+{
+ return (isalpha(ch) || (ch == '_') || (ch == '\\'));
+}
+
+
+/**
+ * IsIdentifierChar
+ *
+ * Return true if the given char is a valid identifier char
+ */
+
+static inline bool IsIdentifierChar (const int ch)
+{
+ return (isalnum(ch) || (ch == '_') || (ch == '@') || (ch == ':') || (ch == '.'));
+}
+
+
+/**
+ * GetOperatorType
+ *
+ * Return:
+ * NO_OPERATOR if char is not an operator
+ * OPERATOR_1CHAR if the operator is one char long
+ * OPERATOR_2CHAR if the operator is two chars long
+ */
+
+static inline int GetOperatorType (const int ch1, const int ch2)
+{
+ int OpType = NO_OPERATOR;
+
+ if ((ch1 == '+') || (ch1 == '-') || (ch1 == '*') || (ch1 == '/') || (ch1 == '#') ||
+ (ch1 == '(') || (ch1 == ')') || (ch1 == '~') || (ch1 == '&') || (ch1 == '|') || (ch1 == ','))
+ OpType = OPERATOR_1CHAR;
+
+ else if ((ch1 == ch2) && (ch1 == '<' || ch1 == '>'))
+ OpType = OPERATOR_2CHAR;
+
+ return OpType;
+}
+
+
+/**
+ * IsBin
+ *
+ * Return true if the given char is 0 or 1
+ */
+
+static inline bool IsBin (const int ch)
+{
+ return (ch == '0') || (ch == '1');
+}
+
+
+/**
+ * IsDoxygenChar
+ *
+ * Return true if the char may be part of a Doxygen keyword
+ */
+
+static inline bool IsDoxygenChar (const int ch)
+{
+ return isalpha(ch) || (ch == '$') || (ch == '[') || (ch == ']') || (ch == '{') || (ch == '}');
+}
+
+
+/**
+ * ColouriseA68kDoc
+ *
+ * Main function, which colourises a 68k source
+ */
+
+static void ColouriseA68kDoc (unsigned int startPos, int length, int initStyle, WordList *keywordlists[], Accessor &styler)
+{
+
+ // Get references to keywords lists
+ WordList &cpuInstruction = *keywordlists[0];
+ WordList ®isters = *keywordlists[1];
+ WordList &directive = *keywordlists[2];
+ WordList &extInstruction = *keywordlists[3];
+ WordList &commentSpecial = *keywordlists[4];
+ WordList &doxygenKeyword = *keywordlists[5];
+
+
+ // Instanciate a context for our source
+ StyleContext sc(startPos, length, initStyle, styler);
+
+
+ /************************************************************
+ *
+ * Parse the text
+ *
+ ************************************************************/
+
+ for ( ; sc.More(); sc.Forward())
+ {
+ char Buffer[100];
+ int OpType;
+
+ // Reset style at beginning of line
+ if (sc.atLineStart)
+ sc.SetState(SCE_A68K_DEFAULT);
+
+
+ /************************************************************
+ *
+ * Handle current state if we are not in the "default style"
+ *
+ ************************************************************/
+
+ if (sc.state != SCE_A68K_DEFAULT)
+ {
+ // Check if current style continue.
+ // If this case, we loop because there is nothing else to do
+ if (((sc.state == SCE_A68K_NUMBER_DEC) && isdigit(sc.ch)) // Decimal number
+ || ((sc.state == SCE_A68K_NUMBER_BIN) && IsBin(sc.ch)) // Binary number
+ || ((sc.state == SCE_A68K_NUMBER_HEX) && isxdigit(sc.ch)) // Hexa number
+ || ((sc.state == SCE_A68K_MACRO_ARG) && isdigit(sc.ch)) // Arg of macro
+ || ((sc.state == SCE_A68K_STRING1) && (sc.ch != '\'')) // String single-quoted
+ || ((sc.state == SCE_A68K_STRING2) && (sc.ch != '\"')) // String double-quoted
+ || ((sc.state == SCE_A68K_MACRO_ARG) && isdigit(sc.ch)) // Macro argument
+ // Label. ' ' and '\t' are needed to handle macro declarations
+ || ((sc.state == SCE_A68K_LABEL) && (sc.ch != ':') && (sc.ch != ' ') && (sc.ch != '\t'))
+ || ((sc.state == SCE_A68K_IDENTIFIER) && (sc.ch < 0x80) && IsIdentifierChar(sc.ch)) // Identifier
+ || ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && IsDoxygenChar(sc.ch)) // Doxygen keyword
+ || ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && isalpha(sc.ch))) // Comment current word
+ {
+ continue;
+ }
+
+ // Check if some states terminate at the current char:
+ // we must include this char in the current style context
+ else if (((sc.state == SCE_A68K_STRING1) && (sc.ch < 0x80) && (sc.ch == '\'')) // String single-quoted
+ || ((sc.state == SCE_A68K_STRING2) && (sc.ch < 0x80) && (sc.ch == '\"')) // String double-quoted
+ || ((sc.state == SCE_A68K_LABEL) && (sc.ch < 0x80) && (sc.ch == ':'))) // Label
+ {
+ sc.ForwardSetState(SCE_A68K_DEFAULT);
+ }
+
+ // Check for special words or Doxygen keywords in comments
+ else if (sc.state == SCE_A68K_COMMENT)
+ {
+ if (sc.ch == '\\') {
+ sc.SetState(SCE_A68K_COMMENT_DOXYGEN);
+ }
+ else if ((sc.ch < 0x80) && isalpha(sc.ch)) {
+ sc.SetState(SCE_A68K_COMMENT_WORD);
+ }
+ continue;
+ }
+
+ // Check for special words in comment
+ else if ((sc.state == SCE_A68K_COMMENT_WORD) && (sc.ch < 0x80) && !isalpha(sc.ch))
+ {
+ sc.GetCurrent(Buffer, sizeof(Buffer));
+ if (commentSpecial.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_COMMENT_SPECIAL);
+ }
+ else {
+ sc.ChangeState(SCE_A68K_COMMENT);
+ }
+ sc.SetState(SCE_A68K_COMMENT);
+ continue;
+ }
+
+ // Check for Doxygen keywords
+ else if ((sc.state == SCE_A68K_COMMENT_DOXYGEN) && (sc.ch < 0x80) && !IsDoxygenChar(sc.ch))
+ {
+ sc.GetCurrentLowered(Buffer, sizeof(Buffer)); // Buffer the string of the current context
+ if (!doxygenKeyword.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_COMMENT);
+ }
+ sc.SetState(SCE_A68K_COMMENT);
+ continue;
+ }
+
+ // Check if we are in the case of a label which terminates without ':'
+ // It should be a macro declaration, not a label
+ else if ((sc.state == SCE_A68K_LABEL) && (sc.ch < 0x80) && ((sc.ch == ' ') || (sc.ch == '\t')))
+ {
+ sc.ChangeState(SCE_A68K_MACRO_DECLARATION);
+ }
+
+ // Check if we are at the end of an identifier
+ // In this case, colourise it if was a keyword.
+ else if ((sc.state == SCE_A68K_IDENTIFIER) && !IsIdentifierChar(sc.ch))
+ {
+ sc.GetCurrentLowered(Buffer, sizeof(Buffer)); // Buffer the string of the current context
+ if (cpuInstruction.InList(Buffer)) { // And check if it belongs to a keyword list
+ sc.ChangeState(SCE_A68K_CPUINSTRUCTION);
+ }
+ else if (extInstruction.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_EXTINSTRUCTION);
+ }
+ else if (registers.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_REGISTER);
+ }
+ else if (directive.InList(Buffer)) {
+ sc.ChangeState(SCE_A68K_DIRECTIVE);
+ }
+ }
+
+ // All special contexts are now handled.Come back to default style
+ sc.SetState(SCE_A68K_DEFAULT);
+ }
+
+
+ /************************************************************
+ *
+ * Check if we must enter a new state
+ *
+ ************************************************************/
+
+ // Label and macro identifiers start at the beginning of a line
+ // We set both as a label, but if it wasn't one (no ':' at the end),
+ // it will be changed as a macro identifier.
+ if (sc.atLineStart && (sc.ch < 0x80) && IsIdentifierStart(sc.ch)) {
+ sc.SetState(SCE_A68K_LABEL);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == ';')) { // Comment
+ sc.SetState(SCE_A68K_COMMENT);
+ }
+ else if ((sc.ch < 0x80) && isdigit(sc.ch)) { // Decimal numbers haven't prefix
+ sc.SetState(SCE_A68K_NUMBER_DEC);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '%')) { // Binary numbers are prefixed with '%'
+ sc.SetState(SCE_A68K_NUMBER_BIN);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '$')) { // Hexadecimal numbers are prefixed with '$'
+ sc.SetState(SCE_A68K_NUMBER_HEX);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '\'')) { // String (single-quoted)
+ sc.SetState(SCE_A68K_STRING1);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '\"')) { // String (double-quoted)
+ sc.SetState(SCE_A68K_STRING2);
+ }
+ else if ((sc.ch < 0x80) && (sc.ch == '\\') && (isdigit(sc.chNext))) { // Replacement symbols in macro
+ sc.SetState(SCE_A68K_MACRO_ARG);
+ }
+ else if ((sc.ch < 0x80) && IsIdentifierStart(sc.ch)) { // An identifier: constant, label, etc...
+ sc.SetState(SCE_A68K_IDENTIFIER);
+ }
+ else {
+ if (sc.ch < 0x80) {
+ OpType = GetOperatorType(sc.ch, sc.chNext); // Check if current char is an operator
+ if (OpType != NO_OPERATOR) {
+ sc.SetState(SCE_A68K_OPERATOR);
+ if (OpType == OPERATOR_2CHAR) { // Check if the operator is 2 bytes long
+ sc.ForwardSetState(SCE_A68K_OPERATOR); // (>> or <<)
+ }
+ }
+ }
+ }
+ } // End of for()
+ sc.Complete();
+}
+
+
+// Names of the keyword lists
+
+static const char * const a68kWordListDesc[] =
+{
+ "CPU instructions",
+ "Registers",
+ "Directives",
+ "Extended instructions",
+ "Comment special words",
+ "Doxygen keywords",
+ 0
+};
+
+LexerModule lmA68k(SCLEX_A68K, ColouriseA68kDoc, "a68k", 0, a68kWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexAPDL.cxx b/plugins/scintilla/scintilla/LexAPDL.cxx
index 7bf597b..7d65a56 100644
--- a/plugins/scintilla/scintilla/LexAPDL.cxx
+++ b/plugins/scintilla/scintilla/LexAPDL.cxx
@@ -8,18 +8,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexASY.cxx b/plugins/scintilla/scintilla/LexASY.cxx
index 5bf979f..9e3470c 100644
--- a/plugins/scintilla/scintilla/LexASY.cxx
+++ b/plugins/scintilla/scintilla/LexASY.cxx
@@ -4,25 +4,26 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
-static void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle,
+static void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0];
@@ -118,7 +119,7 @@ static void ColouriseAsyDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_ASY_IDENTIFIER);
} else if (sc.Match('/', '*')) {
sc.SetState(SCE_ASY_COMMENT);
- sc.Forward(); //
+ sc.Forward(); //
} else if (sc.Match('/', '/')) {
sc.SetState(SCE_ASY_COMMENTLINE);
} else if (sc.ch == '\"') {
@@ -162,14 +163,14 @@ static int ParseASYWord(unsigned int pos, Accessor &styler, char *word)
length++;
ch=styler.SafeGetCharAt(pos+length);
}
- word[length]=0;
+ word[length]=0;
return length;
}
static bool IsASYDrawingLine(int line, Accessor &styler) {
int pos = styler.LineStart(line);
int eol_pos = styler.LineStart(line + 1) - 1;
-
+
int startpos = pos;
char buffer[100]="";
@@ -181,11 +182,11 @@ static bool IsASYDrawingLine(int line, Accessor &styler) {
if (!drawcommands && ch!=' ') return false;
else if (drawcommands) return true;
startpos++;
- }
+ }
return false;
}
-static void FoldAsyDoc(unsigned int startPos, int length, int initStyle,
+static void FoldAsyDoc(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
@@ -236,7 +237,7 @@ static void FoldAsyDoc(unsigned int startPos, int length, int initStyle,
else if (lineCurrent!=0 && IsASYDrawingLine(lineCurrent - 1, styler) &&
!IsASYDrawingLine(lineCurrent+1, styler))
levelNext--;
- }
+ }
if (atEOL) {
int levelUse = levelCurrent;
diff --git a/plugins/scintilla/scintilla/LexAU3.cxx b/plugins/scintilla/scintilla/LexAU3.cxx
index cfff927..72c918f 100644
--- a/plugins/scintilla/scintilla/LexAU3.cxx
+++ b/plugins/scintilla/scintilla/LexAU3.cxx
@@ -1,15 +1,15 @@
// Scintilla source code edit control
// @file LexAU3.cxx
// Lexer for AutoIt3 http://www.hiddensoft.com/autoit3
-// by Jos van der Zande, jvdzande yahoo com
+// by Jos van der Zande, jvdzande yahoo com
//
// Changes:
// March 28, 2004 - Added the standard Folding code
// April 21, 2004 - Added Preprosessor Table + Syntax Highlighting
// Fixed Number highlighting
// Changed default isoperator to IsAOperator to have a better match to AutoIt3
-// Fixed "#comments_start" -> "#comments-start"
-// Fixed "#comments_end" -> "#comments-end"
+// Fixed "#comments_start" -> "#comments-start"
+// Fixed "#comments_end" -> "#comments-end"
// Fixed Sendkeys in Strings when not terminated with }
// Added support for Sendkey strings that have second parameter e.g. {UP 5} or {a down}
// April 26, 2004 - Fixed # pre-processor statement inside of comment block would invalidly change the color.
@@ -25,9 +25,9 @@
// Added fold.compact support set with fold.compact=1
// Changed folding inside of #cs-#ce. Default is no keyword folding inside comment blocks when fold.comment=1
// it will now only happen when fold.comment=2.
-// Sep 5, 2004 - Added logic to handle colourizing words on the last line.
+// Sep 5, 2004 - Added logic to handle colourizing words on the last line.
// Typed Characters now show as "default" till they match any table.
-// Oct 10, 2004 - Added logic to show Comments in "Special" directives.
+// Oct 10, 2004 - Added logic to show Comments in "Special" directives.
// Nov 1, 2004 - Added better testing for Numbers supporting x and e notation.
// Nov 28, 2004 - Added logic to handle continuation lines for syntax highlighting.
// Jan 10, 2005 - Added Abbreviations Keyword used for expansion
@@ -52,18 +52,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -127,7 +130,7 @@ static int GetSendKey(const char *szLine, char *szKey)
}
else if (cTemp == ' ')
{
- // skip other spaces
+ // skip other spaces
}
else if (nFlag == 0)
{
@@ -139,7 +142,7 @@ static int GetSendKey(const char *szLine, char *szKey)
// Save second portion into var...
szSpecial[nSpecPos++] = cTemp;
// check if Second portion is all numbers for repeat fuction
- if (isdigit(cTemp) == false) {nSpecNum = 0;}
+ if (isdigit(cTemp) == false) {nSpecNum = 0;}
}
}
nPos++; // skip to next char
@@ -151,7 +154,7 @@ static int GetSendKey(const char *szLine, char *szKey)
szKey[nKeyPos] = '\0';
szSpecial[nSpecPos] = '\0';
if (strcmp(szSpecial,"down")== 0 || strcmp(szSpecial,"up")== 0 ||
- strcmp(szSpecial,"on")== 0 || strcmp(szSpecial,"off")== 0 ||
+ strcmp(szSpecial,"on")== 0 || strcmp(szSpecial,"off")== 0 ||
strcmp(szSpecial,"toggle")== 0 || nSpecNum == 1 )
{
nFlag = 0;
@@ -160,13 +163,13 @@ static int GetSendKey(const char *szLine, char *szKey)
{
nFlag = 1;
}
- return nFlag; // 1 is bad, 0 is good
+ return nFlag; // 1 is bad, 0 is good
-} // GetSendKey()
+} // GetSendKey()
//
// Routine to check the last "none comment" character on a line to see if its a continuation
-//
+//
static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
{
int nsPos = styler.LineStart(szLine);
@@ -192,7 +195,7 @@ static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
//
// syntax highlighting logic
-static void ColouriseAU3Doc(unsigned int startPos,
+static void ColouriseAU3Doc(unsigned int startPos,
int length, int initStyle,
WordList *keywordlists[],
Accessor &styler) {
@@ -214,19 +217,19 @@ static void ColouriseAU3Doc(unsigned int startPos,
(lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent); // get start position
- initStyle = 0; // reset the start style to 0
+ initStyle = 0; // reset the start style to 0
}
}
// Set the new length to include it from the start and set the start position
length = length + s_startPos - startPos; // correct the total length to process
styler.StartAt(startPos);
-
+
StyleContext sc(startPos, length, initStyle, styler);
char si; // string indicator "=1 '=2
char ni; // Numeric indicator error=9 normal=0 normal+dec=1 hex=2 Enot=3
- char ci; // comment indicator 0=not linecomment(;)
+ char ci; // comment indicator 0=not linecomment(;)
char s_save[100];
- si=0;
+ si=0;
ni=0;
ci=0;
//$$$
@@ -234,8 +237,8 @@ static void ColouriseAU3Doc(unsigned int startPos,
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
// **********************************************
- // save the total current word for eof processing
- if (IsAWordChar(sc.ch) || sc.ch == '}')
+ // save the total current word for eof processing
+ if (IsAWordChar(sc.ch) || sc.ch == '}')
{
strcpy(s_save,s);
int tp = strlen(s_save);
@@ -254,9 +257,9 @@ static void ColouriseAU3Doc(unsigned int startPos,
if (sc.atLineEnd) {
ci=0;
if (strcmp(s, "#ce")== 0 || strcmp(s, "#comments-end")== 0) {
- if (sc.atLineEnd)
+ if (sc.atLineEnd)
sc.SetState(SCE_AU3_DEFAULT);
- else
+ else
sc.SetState(SCE_AU3_COMMENTBLOCK);
}
break;
@@ -267,9 +270,9 @@ static void ColouriseAU3Doc(unsigned int startPos,
sc.SetState(SCE_AU3_COMMENTBLOCK);
}
// skip rest of the line
- if (ci==2)
+ if (ci==2)
break;
- // check when first character is detected on the line
+ // check when first character is detected on the line
if (ci==0) {
if (IsAWordStart(static_cast<char>(sc.ch)) || IsAOperator(static_cast<char>(sc.ch))) {
ci=1;
@@ -292,10 +295,10 @@ static void ColouriseAU3Doc(unsigned int startPos,
}
case SCE_AU3_OPERATOR:
{
- // check if its a COMobject
+ // check if its a COMobject
if (sc.chPrev == '.' && IsAWordChar(sc.ch)) {
sc.SetState(SCE_AU3_COMOBJ);
- }
+ }
else {
sc.SetState(SCE_AU3_DEFAULT);
}
@@ -360,7 +363,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
sc.SetState(SCE_AU3_DEFAULT);
}
}
- }
+ }
if (sc.atLineEnd) {
sc.SetState(SCE_AU3_DEFAULT);}
break;
@@ -433,7 +436,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
case SCE_AU3_STRING:
{
// check for " to end a double qouted string or
- // check for ' to end a single qouted string
+ // check for ' to end a single qouted string
if ((si == 1 && sc.ch == '\"') || (si == 2 && sc.ch == '\'') || (si == 3 && sc.ch == '>'))
{
sc.ForwardSetState(SCE_AU3_DEFAULT);
@@ -445,7 +448,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
si=0;
// at line end and not found a continuation char then reset to default
int lineCurrent = styler.GetLine(sc.currentPos);
- if (!IsContinuationLine(lineCurrent,styler))
+ if (!IsContinuationLine(lineCurrent,styler))
{
sc.SetState(SCE_AU3_DEFAULT);
break;
@@ -456,27 +459,27 @@ static void ColouriseAU3Doc(unsigned int startPos,
sc.SetState(SCE_AU3_SENT);}
break;
}
-
+
case SCE_AU3_SENT:
{
- // Send key string ended
- if (sc.chPrev == '}' && sc.ch != '}')
+ // Send key string ended
+ if (sc.chPrev == '}' && sc.ch != '}')
{
// set color to SENDKEY when valid sendkey .. else set back to regular string
char sk[100];
// split {111 222} and return {111} and check if 222 is valid.
// if return code = 1 then invalid 222 so must be string
- if (GetSendKey(s,sk))
+ if (GetSendKey(s,sk))
{
sc.ChangeState(SCE_AU3_STRING);
}
// if single char between {?} then its ok as sendkey for a single character
- else if (strlen(sk) == 3)
+ else if (strlen(sk) == 3)
{
sc.ChangeState(SCE_AU3_SENT);
}
// if sendkey {111} is in table then ok as sendkey
- else if (keywords4.InList(sk))
+ else if (keywords4.InList(sk))
{
sc.ChangeState(SCE_AU3_SENT);
}
@@ -492,9 +495,9 @@ static void ColouriseAU3Doc(unsigned int startPos,
int nPos = 0;
int nState = 1;
char cTemp;
- while (!(nState == 2) && ((cTemp = s[nPos]) != '\0'))
+ while (!(nState == 2) && ((cTemp = s[nPos]) != '\0'))
{
- if (cTemp == '{' && nState == 1)
+ if (cTemp == '{' && nState == 1)
{
nState = 2;
}
@@ -509,14 +512,14 @@ static void ColouriseAU3Doc(unsigned int startPos,
sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_STRING);
}
- // If invalid character found then assume its a regular string
+ // If invalid character found then assume its a regular string
if (nState == 0) {
sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_STRING);
}
}
// check if next portion is again a sendkey
- if (sc.atLineEnd)
+ if (sc.atLineEnd)
{
sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_DEFAULT);
@@ -547,14 +550,14 @@ static void ColouriseAU3Doc(unsigned int startPos,
else if (sc.ch == '.' && !IsADigit(sc.chNext)) {sc.SetState(SCE_AU3_OPERATOR);}
else if (sc.ch == '@') {sc.SetState(SCE_AU3_KEYWORD);}
//else if (sc.ch == '_') {sc.SetState(SCE_AU3_KEYWORD);}
- else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);} // string after #include
+ else if (sc.ch == '<' && si==3) {sc.SetState(SCE_AU3_STRING);} // string after #include
else if (sc.ch == '\"') {
sc.SetState(SCE_AU3_STRING);
si = 1; }
else if (sc.ch == '\'') {
sc.SetState(SCE_AU3_STRING);
si = 2; }
- else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
+ else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext)))
{
sc.SetState(SCE_AU3_NUMBER);
ni = 0;
@@ -566,7 +569,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
} //for (; sc.More(); sc.Forward())
//*************************************
- // Colourize the last word correctly
+ // Colourize the last word correctly
//*************************************
if (sc.state == SCE_AU3_KEYWORD)
{
@@ -610,24 +613,24 @@ static void ColouriseAU3Doc(unsigned int startPos,
}
if (sc.state == SCE_AU3_SENT)
{
- // Send key string ended
- if (sc.chPrev == '}' && sc.ch != '}')
+ // Send key string ended
+ if (sc.chPrev == '}' && sc.ch != '}')
{
// set color to SENDKEY when valid sendkey .. else set back to regular string
char sk[100];
// split {111 222} and return {111} and check if 222 is valid.
// if return code = 1 then invalid 222 so must be string
- if (GetSendKey(s_save,sk))
+ if (GetSendKey(s_save,sk))
{
sc.ChangeState(SCE_AU3_STRING);
}
// if single char between {?} then its ok as sendkey for a single character
- else if (strlen(sk) == 3)
+ else if (strlen(sk) == 3)
{
sc.ChangeState(SCE_AU3_SENT);
}
// if sendkey {111} is in table then ok as sendkey
- else if (keywords4.InList(sk))
+ else if (keywords4.InList(sk))
{
sc.ChangeState(SCE_AU3_SENT);
}
@@ -638,7 +641,7 @@ static void ColouriseAU3Doc(unsigned int startPos,
sc.SetState(SCE_AU3_STRING);
}
// check if next portion is again a sendkey
- if (sc.atLineEnd)
+ if (sc.atLineEnd)
{
sc.ChangeState(SCE_AU3_STRING);
sc.SetState(SCE_AU3_DEFAULT);
@@ -655,7 +658,7 @@ static bool IsStreamCommentStyle(int style) {
//
// Routine to find first none space on the current line and return its Style
-// needed for comment lines not starting on pos 1
+// needed for comment lines not starting on pos 1
static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
{
int nsPos = styler.LineStart(szLine);
@@ -687,7 +690,7 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
startPos = styler.LineStart(lineCurrent);
}
}
- // vars for style of previous/current/next lines
+ // vars for style of previous/current/next lines
int style = GetStyleFirstWord(lineCurrent,styler);
int stylePrev = 0;
// find the first previous line without continuation character at the end
@@ -712,7 +715,7 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
int levelNext = levelCurrent;
- //
+ //
int visibleChars = 0;
char chNext = styler.SafeGetCharAt(startPos);
char chPrev = ' ';
@@ -737,7 +740,7 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
}
}
}
- // start the capture of the first word
+ // start the capture of the first word
if (!(FirstWordStart)) {
if (IsAWordChar(ch) || IsAWordStart(ch) || ch == ';') {
FirstWordStart = true;
@@ -749,7 +752,7 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
if (ThenFoundLast) {
if (IsAWordChar(ch)) {
ThenFoundLast = false;
- }
+ }
}
// find out if the word "then" is the last on a "if" line
if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
@@ -770,21 +773,21 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
}
}
}
- // End of Line found so process the information
+ // End of Line found so process the information
if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
// **************************
// Folding logic for Keywords
// **************************
// if a keyword is found on the current line and the line doesn't end with _ (continuation)
// and we are not inside a commentblock.
- if (szKeywordlen > 0 && (!(chPrev == '_')) &&
+ if (szKeywordlen > 0 && (!(chPrev == '_')) &&
((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
szKeyword[szKeywordlen] = '\0';
// only fold "if" last keyword is "then" (else its a one line if)
if (strcmp(szKeyword,"if") == 0 && ThenFoundLast) {
levelNext++;
}
- // create new fold for these words
+ // create new fold for these words
if (strcmp(szKeyword,"do") == 0 || strcmp(szKeyword,"for") == 0 ||
strcmp(szKeyword,"func") == 0 || strcmp(szKeyword,"while") == 0||
strcmp(szKeyword,"with") == 0 || strcmp(szKeyword,"#region") == 0 ) {
@@ -797,12 +800,12 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
}
// end the fold for these words before the current line
if (strcmp(szKeyword,"endfunc") == 0 || strcmp(szKeyword,"endif") == 0 ||
- strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 ||
+ strcmp(szKeyword,"next") == 0 || strcmp(szKeyword,"until") == 0 ||
strcmp(szKeyword,"endwith") == 0 ||strcmp(szKeyword,"wend") == 0){
levelNext--;
levelCurrent--;
}
- // end the fold for these words before the current line and Start new fold
+ // end the fold for these words before the current line and Start new fold
if (strcmp(szKeyword,"case") == 0 || strcmp(szKeyword,"else") == 0 ||
strcmp(szKeyword,"elseif") == 0 ) {
levelCurrent--;
@@ -841,16 +844,16 @@ static void FoldAU3Doc(unsigned int startPos, int length, int, WordList *[], Acc
// Start of a comment block
if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
levelNext++;
- }
+ }
// fold till the last line for normal comment lines
- else if (IsStreamCommentStyle(stylePrev)
+ else if (IsStreamCommentStyle(stylePrev)
&& !(styleNext == SCE_AU3_COMMENT)
- && stylePrev == SCE_AU3_COMMENT
+ && stylePrev == SCE_AU3_COMMENT
&& style == SCE_AU3_COMMENT) {
levelNext--;
}
// fold till the one but last line for Blockcomment lines
- else if (IsStreamCommentStyle(stylePrev)
+ else if (IsStreamCommentStyle(stylePrev)
&& !(styleNext == SCE_AU3_COMMENTBLOCK)
&& style == SCE_AU3_COMMENTBLOCK) {
levelNext--;
diff --git a/plugins/scintilla/scintilla/LexAVE.cxx b/plugins/scintilla/scintilla/LexAVE.cxx
index 2b7029b..373173c 100644
--- a/plugins/scintilla/scintilla/LexAVE.cxx
+++ b/plugins/scintilla/scintilla/LexAVE.cxx
@@ -9,18 +9,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -42,7 +45,7 @@ inline bool IsAWordStart(const int ch) {
}
inline bool isAveOperator(char ch) {
- if (isalnum(ch))
+ if (isascii(ch) && isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
diff --git a/plugins/scintilla/scintilla/LexAbaqus.cxx b/plugins/scintilla/scintilla/LexAbaqus.cxx
index 10e8b76..1341700 100644
--- a/plugins/scintilla/scintilla/LexAbaqus.cxx
+++ b/plugins/scintilla/scintilla/LexAbaqus.cxx
@@ -10,18 +10,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexAccessor.h b/plugins/scintilla/scintilla/LexAccessor.h
new file mode 100644
index 0000000..dccf31e
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexAccessor.h
@@ -0,0 +1,175 @@
+// Scintilla source code edit control
+/** @file LexAccessor.h
+ ** Interfaces between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXACCESSOR_H
+#define LEXACCESSOR_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class LexAccessor {
+private:
+ IDocument *pAccess;
+ enum {extremePosition=0x7FFFFFFF};
+ /** @a bufferSize is a trade off between time taken to copy the characters
+ * and retrieval overhead.
+ * @a slopSize positions the buffer before the desired position
+ * in case there is some backtracking. */
+ enum {bufferSize=4000, slopSize=bufferSize/8};
+ char buf[bufferSize+1];
+ int startPos;
+ int endPos;
+ int codePage;
+ int lenDoc;
+ int mask;
+ char styleBuf[bufferSize];
+ int validLen;
+ char chFlags;
+ char chWhile;
+ unsigned int startSeg;
+ int startPosStyling;
+
+ void Fill(int position) {
+ startPos = position - slopSize;
+ if (startPos + bufferSize > lenDoc)
+ startPos = lenDoc - bufferSize;
+ if (startPos < 0)
+ startPos = 0;
+ endPos = startPos + bufferSize;
+ if (endPos > lenDoc)
+ endPos = lenDoc;
+
+ pAccess->GetCharRange(buf, startPos, endPos-startPos);
+ buf[endPos-startPos] = '\0';
+ }
+
+public:
+ LexAccessor(IDocument *pAccess_) :
+ pAccess(pAccess_), startPos(extremePosition), endPos(0),
+ codePage(pAccess->CodePage()), lenDoc(pAccess->Length()),
+ mask(127), validLen(0), chFlags(0), chWhile(0),
+ startSeg(0), startPosStyling(0) {
+ }
+ char operator[](int position) {
+ if (position < startPos || position >= endPos) {
+ Fill(position);
+ }
+ return buf[position - startPos];
+ }
+ /** Safe version of operator[], returning a defined value for invalid position. */
+ char SafeGetCharAt(int position, char chDefault=' ') {
+ if (position < startPos || position >= endPos) {
+ Fill(position);
+ if (position < startPos || position >= endPos) {
+ // Position is outside range of document
+ return chDefault;
+ }
+ }
+ return buf[position - startPos];
+ }
+ bool IsLeadByte(char ch) {
+ return pAccess->IsDBCSLeadByte(ch);
+ }
+
+ bool Match(int pos, const char *s) {
+ for (int i=0; *s; i++) {
+ if (*s != SafeGetCharAt(pos+i))
+ return false;
+ s++;
+ }
+ return true;
+ }
+ char StyleAt(int position) {
+ return static_cast<char>(pAccess->StyleAt(position) & mask);
+ }
+ int GetLine(int position) {
+ return pAccess->LineFromPosition(position);
+ }
+ int LineStart(int line) {
+ return pAccess->LineStart(line);
+ }
+ int LevelAt(int line) {
+ return pAccess->GetLevel(line);
+ }
+ int Length() const {
+ return lenDoc;
+ }
+ void Flush() {
+ startPos = extremePosition;
+ if (validLen > 0) {
+ pAccess->SetStyles(validLen, styleBuf);
+ startPosStyling += validLen;
+ validLen = 0;
+ }
+ }
+ int GetLineState(int line) {
+ return pAccess->GetLineState(line);
+ }
+ int SetLineState(int line, int state) {
+ return pAccess->SetLineState(line, state);
+ }
+ // Style setting
+ void StartAt(unsigned int start, char chMask=31) {
+ // Store the mask specified for use with StyleAt.
+ mask = chMask;
+ pAccess->StartStyling(start, chMask);
+ startPosStyling = start;
+ }
+ void SetFlags(char chFlags_, char chWhile_) {
+ chFlags = chFlags_;
+ chWhile = chWhile_;
+ }
+ unsigned int GetStartSegment() const {
+ return startSeg;
+ }
+ void StartSegment(unsigned int pos) {
+ startSeg = pos;
+ }
+ void ColourTo(unsigned int pos, int chAttr) {
+ // Only perform styling if non empty range
+ if (pos != startSeg - 1) {
+ assert(pos >= startSeg);
+ if (pos < startSeg) {
+ return;
+ }
+
+ if (validLen + (pos - startSeg + 1) >= bufferSize)
+ Flush();
+ if (validLen + (pos - startSeg + 1) >= bufferSize) {
+ // Too big for buffer so send directly
+ pAccess->SetStyleFor(pos - startSeg + 1, static_cast<char>(chAttr));
+ } else {
+ if (chAttr != chWhile)
+ chFlags = 0;
+ chAttr |= chFlags;
+ for (unsigned int i = startSeg; i <= pos; i++) {
+ assert((startPosStyling + validLen) < Length());
+ styleBuf[validLen++] = static_cast<char>(chAttr);
+ }
+ }
+ }
+ startSeg = pos+1;
+ }
+ void SetLevel(int line, int level) {
+ pAccess->SetLevel(line, level);
+ }
+ void IndicatorFill(int start, int end, int indicator, int value) {
+ pAccess->DecorationSetCurrentIndicator(indicator);
+ pAccess->DecorationFillRange(start, value, end - start);
+ }
+
+ void ChangeLexerState(int start, int end) {
+ pAccess->ChangeLexerState(start, end);
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LexAda.cxx b/plugins/scintilla/scintilla/LexAda.cxx
old mode 100755
new mode 100644
index 654bfbe..e109514
--- a/plugins/scintilla/scintilla/LexAda.cxx
+++ b/plugins/scintilla/scintilla/LexAda.cxx
@@ -6,19 +6,23 @@
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
-#include <ctype.h>
#include <string.h>
#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
#include <string>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "PropSet.h"
-#include "KeyWords.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexAsm.cxx b/plugins/scintilla/scintilla/LexAsm.cxx
index 17c9384..946d47a 100644
--- a/plugins/scintilla/scintilla/LexAsm.cxx
+++ b/plugins/scintilla/scintilla/LexAsm.cxx
@@ -4,25 +4,37 @@
** Written by The Black Horus
** Enhancements and NASM stuff by Kein-Hong Man, 2003-10
** SCE_ASM_COMMENTBLOCK and SCE_ASM_CHARACTER are for future GNU as colouring
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
**/
// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
-#include "Platform.h"
+#include <string>
+#include <map>
+#include <set>
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
@@ -50,15 +62,184 @@ static inline bool IsAsmOperator(const int ch) {
return false;
}
-static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_ASM_COMMENTDIRECTIVE || style == SCE_ASM_COMMENTBLOCK;
+}
+
+static inline int LowerCase(int c) {
+ if (c >= 'A' && c <= 'Z')
+ return 'a' + c - 'A';
+ return c;
+}
+
+// An individual named option for use in an OptionSet
- WordList &cpuInstruction = *keywordlists[0];
- WordList &mathInstruction = *keywordlists[1];
- WordList ®isters = *keywordlists[2];
- WordList &directive = *keywordlists[3];
- WordList &directiveOperand = *keywordlists[4];
- WordList &extInstruction = *keywordlists[5];
+// Options used for LexerAsm
+struct OptionsAsm {
+ std::string delimiter;
+ bool fold;
+ bool foldSyntaxBased;
+ bool foldCommentMultiline;
+ bool foldCommentExplicit;
+ std::string foldExplicitStart;
+ std::string foldExplicitEnd;
+ bool foldExplicitAnywhere;
+ bool foldCompact;
+ OptionsAsm() {
+ delimiter = "";
+ fold = false;
+ foldSyntaxBased = true;
+ foldCommentMultiline = false;
+ foldCommentExplicit = false;
+ foldExplicitStart = "";
+ foldExplicitEnd = "";
+ foldExplicitAnywhere = false;
+ foldCompact = true;
+ }
+};
+
+static const char * const asmWordListDesc[] = {
+ "CPU instructions",
+ "FPU instructions",
+ "Registers",
+ "Directives",
+ "Directive operands",
+ "Extended instructions",
+ "Directives4Foldstart",
+ "Directives4Foldend",
+ 0
+};
+
+struct OptionSetAsm : public OptionSet<OptionsAsm> {
+ OptionSetAsm() {
+ DefineProperty("lexer.asm.comment.delimiter", &OptionsAsm::delimiter,
+ "Character used for COMMENT directive's delimiter, replacing the standard \"~\".");
+
+ DefineProperty("fold", &OptionsAsm::fold);
+
+ DefineProperty("fold.asm.syntax.based", &OptionsAsm::foldSyntaxBased,
+ "Set this property to 0 to disable syntax based folding.");
+
+ DefineProperty("fold.asm.comment.multiline", &OptionsAsm::foldCommentMultiline,
+ "Set this property to 1 to enable folding multi-line comments.");
+
+ DefineProperty("fold.asm.comment.explicit", &OptionsAsm::foldCommentExplicit,
+ "This option enables folding explicit fold points when using the Asm lexer. "
+ "Explicit fold points allows adding extra folding by placing a ;{ comment at the start and a ;} "
+ "at the end of a section that should fold.");
+
+ DefineProperty("fold.asm.explicit.start", &OptionsAsm::foldExplicitStart,
+ "The string to use for explicit fold start points, replacing the standard ;{.");
+
+ DefineProperty("fold.asm.explicit.end", &OptionsAsm::foldExplicitEnd,
+ "The string to use for explicit fold end points, replacing the standard ;}.");
+
+ DefineProperty("fold.asm.explicit.anywhere", &OptionsAsm::foldExplicitAnywhere,
+ "Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+ DefineProperty("fold.compact", &OptionsAsm::foldCompact);
+
+ DefineWordListSets(asmWordListDesc);
+ }
+};
+
+class LexerAsm : public ILexer {
+ WordList cpuInstruction;
+ WordList mathInstruction;
+ WordList registers;
+ WordList directive;
+ WordList directiveOperand;
+ WordList extInstruction;
+ WordList directives4foldstart;
+ WordList directives4foldend;
+ OptionsAsm options;
+ OptionSetAsm osAsm;
+public:
+ LexerAsm() {
+ }
+ ~LexerAsm() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char * SCI_METHOD PropertyNames() {
+ return osAsm.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osAsm.PropertyType(name);
+ }
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osAsm.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osAsm.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ 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);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactoryAsm() {
+ return new LexerAsm();
+ }
+};
+
+int SCI_METHOD LexerAsm::PropertySet(const char *key, const char *val) {
+ if (osAsm.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerAsm::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &cpuInstruction;
+ break;
+ case 1:
+ wordListN = &mathInstruction;
+ break;
+ case 2:
+ wordListN = ®isters;
+ break;
+ case 3:
+ wordListN = &directive;
+ break;
+ case 4:
+ wordListN = &directiveOperand;
+ break;
+ case 5:
+ wordListN = &extInstruction;
+ break;
+ case 6:
+ wordListN = &directives4foldstart;
+ break;
+ case 7:
+ wordListN = &directives4foldend;
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerAsm::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
// Do not leak onto next line
if (initStyle == SCE_ASM_STRINGEOL)
@@ -92,7 +273,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
if (!IsAsmOperator(sc.ch)) {
sc.SetState(SCE_ASM_DEFAULT);
}
- }else if (sc.state == SCE_ASM_NUMBER) {
+ } else if (sc.state == SCE_ASM_NUMBER) {
if (!IsAWordChar(sc.ch)) {
sc.SetState(SCE_ASM_DEFAULT);
}
@@ -100,6 +281,7 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
if (!IsAWordChar(sc.ch) ) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
+ bool IsDirective = false;
if (cpuInstruction.InList(s)) {
sc.ChangeState(SCE_ASM_CPUINSTRUCTION);
@@ -109,15 +291,32 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
sc.ChangeState(SCE_ASM_REGISTER);
} else if (directive.InList(s)) {
sc.ChangeState(SCE_ASM_DIRECTIVE);
+ IsDirective = true;
} else if (directiveOperand.InList(s)) {
sc.ChangeState(SCE_ASM_DIRECTIVEOPERAND);
} else if (extInstruction.InList(s)) {
sc.ChangeState(SCE_ASM_EXTINSTRUCTION);
}
sc.SetState(SCE_ASM_DEFAULT);
+ if (IsDirective && !strcmp(s, "comment")) {
+ char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
+ while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd) {
+ sc.ForwardSetState(SCE_ASM_DEFAULT);
+ }
+ if (sc.ch == delimiter) {
+ sc.SetState(SCE_ASM_COMMENTDIRECTIVE);
+ }
+ }
}
- }
- else if (sc.state == SCE_ASM_COMMENT ) {
+ } else if (sc.state == SCE_ASM_COMMENTDIRECTIVE) {
+ char delimiter = options.delimiter.empty() ? '~' : options.delimiter.c_str()[0];
+ if (sc.ch == delimiter) {
+ while (!sc.atLineEnd) {
+ sc.Forward();
+ }
+ sc.SetState(SCE_ASM_DEFAULT);
+ }
+ } else if (sc.state == SCE_ASM_COMMENT ) {
if (sc.atLineEnd) {
sc.SetState(SCE_ASM_DEFAULT);
}
@@ -166,15 +365,100 @@ static void ColouriseAsmDoc(unsigned int startPos, int length, int initStyle, Wo
sc.Complete();
}
-static const char * const asmWordListDesc[] = {
- "CPU instructions",
- "FPU instructions",
- "Registers",
- "Directives",
- "Directive operands",
- "Extended instructions",
- 0
-};
+// Store both the current line's fold level and the next lines in the
+// level store to make it easy to pick up with each increment
+// and to make it possible to fiddle the current level for "else".
+
+void SCI_METHOD LexerAsm::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+
+ if (!options.fold)
+ return;
+
+ LexAccessor styler(pAccess);
+
+ unsigned int endPos = startPos + length;
+ int visibleChars = 0;
+ int lineCurrent = styler.GetLine(startPos);
+ int levelCurrent = SC_FOLDLEVELBASE;
+ if (lineCurrent > 0)
+ levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
+ int levelNext = levelCurrent;
+ char chNext = styler[startPos];
+ int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
+ char word[100];
+ int wordlen = 0;
+ const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
+ for (unsigned int i = startPos; i < endPos; i++) {
+ char ch = chNext;
+ chNext = styler.SafeGetCharAt(i + 1);
+ int stylePrev = style;
+ style = styleNext;
+ styleNext = styler.StyleAt(i + 1);
+ bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
+ if (options.foldCommentMultiline && IsStreamCommentStyle(style)) {
+ if (!IsStreamCommentStyle(stylePrev)) {
+ levelNext++;
+ } else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
+ // Comments don't end at end of line and the next character may be unstyled.
+ levelNext--;
+ }
+ }
+ if (options.foldCommentExplicit && ((style == SCE_ASM_COMMENT) || options.foldExplicitAnywhere)) {
+ if (userDefinedFoldMarkers) {
+ if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ levelNext++;
+ } else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ levelNext--;
+ }
+ } else {
+ if (ch == ';') {
+ if (chNext == '{') {
+ levelNext++;
+ } else if (chNext == '}') {
+ levelNext--;
+ }
+ }
+ }
+ }
+ if (options.foldSyntaxBased && (style == SCE_ASM_DIRECTIVE)) {
+ word[wordlen++] = static_cast<char>(LowerCase(ch));
+ if (wordlen == 100) { // prevent overflow
+ word[0] = '\0';
+ wordlen = 1;
+ }
+ if (styleNext != SCE_ASM_DIRECTIVE) { // reading directive ready
+ word[wordlen] = '\0';
+ wordlen = 0;
+ if (directives4foldstart.InList(word)) {
+ levelNext++;
+ } else if (directives4foldend.InList(word)){
+ levelNext--;
+ }
+ }
+ }
+ if (!IsASpace(ch))
+ visibleChars++;
+ if (atEOL || (i == endPos-1)) {
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && options.foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent)) {
+ styler.SetLevel(lineCurrent, lev);
+ }
+ lineCurrent++;
+ levelCurrent = levelNext;
+ if (atEOL && (i == static_cast<unsigned int>(styler.Length()-1))) {
+ // There is an empty line at end of file so give it same level and empty
+ styler.SetLevel(lineCurrent, (levelCurrent | levelCurrent << 16) | SC_FOLDLEVELWHITEFLAG);
+ }
+ visibleChars = 0;
+ }
+ }
+}
-LexerModule lmAsm(SCLEX_ASM, ColouriseAsmDoc, "asm", 0, asmWordListDesc);
+LexerModule lmAsm(SCLEX_ASM, LexerAsm::LexerFactoryAsm, "asm", asmWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexAsn1.cxx b/plugins/scintilla/scintilla/LexAsn1.cxx
index 36f1d5d..3545b3f 100644
--- a/plugins/scintilla/scintilla/LexAsn1.cxx
+++ b/plugins/scintilla/scintilla/LexAsn1.cxx
@@ -5,20 +5,23 @@
// Copyright 2004 by Herr Pfarrer rpfarrer <at> yahoo <dot> de
// Last Updated: 20/07/2004
// The License.txt file describes the conditions under which this software may be distributed.
+
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexBaan.cxx b/plugins/scintilla/scintilla/LexBaan.cxx
index a6847db..3784f3c 100644
--- a/plugins/scintilla/scintilla/LexBaan.cxx
+++ b/plugins/scintilla/scintilla/LexBaan.cxx
@@ -8,18 +8,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexBash.cxx b/plugins/scintilla/scintilla/LexBash.cxx
index 5801278..165e104 100644
--- a/plugins/scintilla/scintilla/LexBash.cxx
+++ b/plugins/scintilla/scintilla/LexBash.cxx
@@ -2,44 +2,53 @@
/** @file LexBash.cxx
** Lexer for Bash.
**/
-// Copyright 2004-2008 by Neil Hodgson <neilh scintilla org>
+// Copyright 2004-2010 by Neil Hodgson <neilh scintilla org>
// Adapted from LexPerl by Kein-Hong Man 2004
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
-#define HERE_DELIM_MAX 256
+#define HERE_DELIM_MAX 256
// define this if you want 'invalid octals' to be marked as errors
// usually, this is not a good idea, permissive lexing is better
#undef PEDANTIC_OCTAL
-#define BASH_BASE_ERROR 65
-#define BASH_BASE_DECIMAL 66
-#define BASH_BASE_HEX 67
+#define BASH_BASE_ERROR 65
+#define BASH_BASE_DECIMAL 66
+#define BASH_BASE_HEX 67
#ifdef PEDANTIC_OCTAL
-#define BASH_BASE_OCTAL 68
-#define BASH_BASE_OCTAL_ERROR 69
+#define BASH_BASE_OCTAL 68
+#define BASH_BASE_OCTAL_ERROR 69
#endif
+// state constants for parts of a bash command segment
+#define BASH_CMD_BODY 0
+#define BASH_CMD_START 1
+#define BASH_CMD_WORD 2
+#define BASH_CMD_TEST 3
+#define BASH_CMD_ARITH 4
+#define BASH_CMD_DELIM 5
+
static inline int translateBashDigit(int ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
@@ -80,11 +89,15 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0];
+ WordList cmdDelimiter, bashStruct, bashStruct_in;
+ cmdDelimiter.Set("| || |& & && ; ;; ( ) { }");
+ bashStruct.Set("if elif fi while until else then do done esac eval");
+ bashStruct_in.Set("for case select");
CharacterSet setWordStart(CharacterSet::setAlpha, "_");
// note that [+-] are often parts of identifiers in shell scripts
CharacterSet setWord(CharacterSet::setAlphaNum, "._+-");
- CharacterSet setBashOperator(CharacterSet::setNone, "^&\\%()-+=|{}[]:;>,*/<?!.~@");
+ CharacterSet setBashOperator(CharacterSet::setNone, "^&%()-+=|{}[]:;>,*/<?!.~@");
CharacterSet setSingleCharOp(CharacterSet::setNone, "rwxoRWXOezsfdlpSbctugkTBMACahGLNn");
CharacterSet setParam(CharacterSet::setAlphaNum, "$_");
CharacterSet setHereDoc(CharacterSet::setAlpha, "_\\-+!");
@@ -144,46 +157,115 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
int numBase = 0;
int digit;
unsigned int endPos = startPos + length;
+ int cmdState = BASH_CMD_START;
+ int testExprType = 0;
- // Backtrack to beginning of style if required...
- // If in a long distance lexical state, backtrack to find quote characters
- if (initStyle == SCE_SH_HERE_Q) {
- while ((startPos > 1) && (styler.StyleAt(startPos) != SCE_SH_HERE_DELIM)) {
- startPos--;
- }
- startPos = styler.LineStart(styler.GetLine(startPos));
- initStyle = styler.StyleAt(startPos - 1);
- }
- // Bash strings can be multi-line with embedded newlines, so backtrack.
- // Bash numbers have additional state during lexing, so backtrack too.
- if (initStyle == SCE_SH_STRING
- || initStyle == SCE_SH_BACKTICKS
- || initStyle == SCE_SH_CHARACTER
- || initStyle == SCE_SH_NUMBER
- || initStyle == SCE_SH_IDENTIFIER
- || initStyle == SCE_SH_COMMENTLINE) {
- while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
- startPos--;
- }
- initStyle = SCE_SH_DEFAULT;
+ // 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);
+ for (;;) {
+ startPos = styler.LineStart(ln);
+ if (ln == 0 || styler.GetLineState(ln) == BASH_CMD_START)
+ break;
+ ln--;
}
+ initStyle = SCE_SH_DEFAULT;
StyleContext sc(startPos, endPos - startPos, initStyle, styler);
for (; sc.More(); sc.Forward()) {
+ // handle line continuation, updates per-line stored state
+ if (sc.atLineStart) {
+ ln = styler.GetLine(sc.currentPos);
+ if (sc.state == SCE_SH_STRING
+ || sc.state == SCE_SH_BACKTICKS
+ || sc.state == SCE_SH_CHARACTER
+ || sc.state == SCE_SH_HERE_Q
+ || sc.state == SCE_SH_COMMENTLINE
+ || sc.state == SCE_SH_PARAM) {
+ // force backtrack while retaining cmdState
+ styler.SetLineState(ln, BASH_CMD_BODY);
+ } else {
+ if (ln > 0) {
+ if ((sc.GetRelative(-3) == '\\' && sc.GetRelative(-2) == '\r' && sc.chPrev == '\n')
+ || sc.GetRelative(-2) == '\\') { // handle '\' line continuation
+ // retain last line's state
+ } else
+ cmdState = BASH_CMD_START;
+ }
+ styler.SetLineState(ln, cmdState);
+ }
+ }
+
+ // controls change of cmdState at the end of a non-whitespace element
+ // states BODY|TEST|ARITH persist until the end of a command segment
+ // state WORD persist, but ends with 'in' or 'do' construct keywords
+ int cmdStateNew = BASH_CMD_BODY;
+ if (cmdState == BASH_CMD_TEST || cmdState == BASH_CMD_ARITH || cmdState == BASH_CMD_WORD)
+ cmdStateNew = cmdState;
+ int stylePrev = sc.state;
+
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_SH_OPERATOR:
sc.SetState(SCE_SH_DEFAULT);
+ if (cmdState == BASH_CMD_DELIM) // if command delimiter, start new command
+ cmdStateNew = BASH_CMD_START;
+ else if (sc.chPrev == '\\') // propagate command state if line continued
+ cmdStateNew = cmdState;
break;
case SCE_SH_WORD:
// "." never used in Bash variable names but used in file names
if (!setWord.Contains(sc.ch)) {
- char s[1000];
+ char s[500];
+ char s2[10];
sc.GetCurrent(s, sizeof(s));
- if (s[0] != '-' && // for file operators
- !keywords.InList(s)) {
+ // allow keywords ending in a whitespace or command delimiter
+ s2[0] = static_cast<char>(sc.ch);
+ s2[1] = '\0';
+ bool keywordEnds = IsASpace(sc.ch) || cmdDelimiter.InList(s2);
+ // 'in' or 'do' may be construct keywords
+ if (cmdState == BASH_CMD_WORD) {
+ if (strcmp(s, "in") == 0 && keywordEnds)
+ cmdStateNew = BASH_CMD_BODY;
+ else if (strcmp(s, "do") == 0 && keywordEnds)
+ cmdStateNew = BASH_CMD_START;
+ else
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ sc.SetState(SCE_SH_DEFAULT);
+ break;
+ }
+ // a 'test' keyword starts a test expression
+ if (strcmp(s, "test") == 0) {
+ if (cmdState == BASH_CMD_START && keywordEnds) {
+ cmdStateNew = BASH_CMD_TEST;
+ testExprType = 0;
+ } else
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ }
+ // detect bash construct keywords
+ else if (bashStruct.InList(s)) {
+ if (cmdState == BASH_CMD_START && keywordEnds)
+ cmdStateNew = BASH_CMD_START;
+ else
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ }
+ // 'for'|'case'|'select' needs 'in'|'do' to be highlighted later
+ else if (bashStruct_in.InList(s)) {
+ if (cmdState == BASH_CMD_START && keywordEnds)
+ cmdStateNew = BASH_CMD_WORD;
+ else
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ }
+ // disambiguate option items and file test operators
+ else if (s[0] == '-') {
+ if (cmdState != BASH_CMD_TEST)
+ sc.ChangeState(SCE_SH_IDENTIFIER);
+ }
+ // disambiguate keywords and identifiers
+ else if (cmdState != BASH_CMD_START
+ || !(keywords.InList(s) && keywordEnds)) {
sc.ChangeState(SCE_SH_IDENTIFIER);
}
sc.SetState(SCE_SH_DEFAULT);
@@ -248,14 +330,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_SH_DEFAULT);
break;
case SCE_SH_COMMENTLINE:
- if (sc.ch == '\\' && (sc.chNext == '\r' || sc.chNext == '\n')) {
- // comment continuation
- sc.Forward();
- if (sc.ch == '\r' && sc.chNext == '\n') {
- sc.Forward();
- }
- } else if (sc.atLineEnd) {
- sc.ForwardSetState(SCE_SH_DEFAULT);
+ if (sc.atLineEnd && sc.chPrev != '\\') {
+ sc.SetState(SCE_SH_DEFAULT);
}
break;
case SCE_SH_HERE_DELIM:
@@ -294,23 +370,14 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
HereDoc.State = 1;
}
} else if (HereDoc.State == 1) { // collect the delimiter
- if (HereDoc.Quoted) { // a quoted here-doc delimiter
- if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
- sc.ForwardSetState(SCE_SH_DEFAULT);
- } else {
- if (sc.ch == '\\' && sc.chNext == HereDoc.Quote) { // escaped quote
- sc.Forward();
- }
- HereDoc.Append(sc.ch);
- }
- } else { // an unquoted here-doc delimiter
- if (setHereDoc2.Contains(sc.ch)) {
- HereDoc.Append(sc.ch);
- } else if (sc.ch == '\\') {
- // skip escape prefix
- } else {
- sc.SetState(SCE_SH_DEFAULT);
- }
+ if (setHereDoc2.Contains(sc.ch) || sc.chPrev == '\\') {
+ HereDoc.Append(sc.ch);
+ } else if (HereDoc.Quoted && sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ } else if (sc.ch == '\\') {
+ // skip escape prefix
+ } else {
+ sc.SetState(SCE_SH_DEFAULT);
}
if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force blowup
sc.SetState(SCE_SH_ERROR);
@@ -339,8 +406,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
if (s[strlen(s) - 1] == '\r')
s[strlen(s) - 1] = '\0';
if (strcmp(HereDoc.Delimiter, s) == 0) {
- if ((prefixws > 0 && HereDoc.Indent) || // indentation rule
- (prefixws == 0 && !HereDoc.Indent)) {
+ if ((prefixws == 0) || // indentation rule
+ (prefixws > 0 && HereDoc.Indent)) {
sc.SetState(SCE_SH_DEFAULT);
break;
}
@@ -391,10 +458,17 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_SH_HERE_Q);
}
+ // update cmdState about the current command segment
+ if (stylePrev != SCE_SH_DEFAULT && sc.state == SCE_SH_DEFAULT) {
+ cmdState = cmdStateNew;
+ }
// Determine if a new state should be entered.
if (sc.state == SCE_SH_DEFAULT) {
- if (sc.ch == '\\') { // escaped character
+ if (sc.ch == '\\') {
+ // Bash can escape any non-newline as a literal
sc.SetState(SCE_SH_IDENTIFIER);
+ if (sc.chNext == '\r' || sc.chNext == '\n')
+ sc.SetState(SCE_SH_OPERATOR);
} else if (IsADigit(sc.ch)) {
sc.SetState(SCE_SH_NUMBER);
numBase = BASH_BASE_DECIMAL;
@@ -424,6 +498,10 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_SH_BACKTICKS);
Quote.Start(sc.ch);
} else if (sc.ch == '$') {
+ if (sc.Match("$((")) {
+ sc.SetState(SCE_SH_OPERATOR); // handle '((' later
+ continue;
+ }
sc.SetState(SCE_SH_SCALAR);
sc.Forward();
if (sc.ch == '{') {
@@ -434,9 +512,6 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.ChangeState(SCE_SH_STRING);
} else if (sc.ch == '(' || sc.ch == '`') {
sc.ChangeState(SCE_SH_BACKTICKS);
- if (sc.chNext == '(') { // $(( is lexed as operator
- sc.ChangeState(SCE_SH_OPERATOR);
- }
} else {
continue; // scalar has no delimiter pair
}
@@ -453,9 +528,66 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_SH_WORD);
sc.Forward();
} else if (setBashOperator.Contains(sc.ch)) {
+ char s[10];
+ bool isCmdDelim = false;
sc.SetState(SCE_SH_OPERATOR);
+ // handle opening delimiters for test/arithmetic expressions - ((,[[,[
+ if (cmdState == BASH_CMD_START
+ || cmdState == BASH_CMD_BODY) {
+ if (sc.Match('(', '(')) {
+ cmdState = BASH_CMD_ARITH;
+ sc.Forward();
+ } else if (sc.Match('[', '[') && IsASpace(sc.GetRelative(2))) {
+ cmdState = BASH_CMD_TEST;
+ testExprType = 1;
+ sc.Forward();
+ } else if (sc.ch == '[' && IsASpace(sc.chNext)) {
+ cmdState = BASH_CMD_TEST;
+ testExprType = 2;
+ }
+ }
+ // special state -- for ((x;y;z)) in ... looping
+ if (cmdState == BASH_CMD_WORD && sc.Match('(', '(')) {
+ cmdState = BASH_CMD_ARITH;
+ sc.Forward();
+ continue;
+ }
+ // handle command delimiters in command START|BODY|WORD state, also TEST if 'test'
+ if (cmdState == BASH_CMD_START
+ || cmdState == BASH_CMD_BODY
+ || cmdState == BASH_CMD_WORD
+ || (cmdState == BASH_CMD_TEST && testExprType == 0)) {
+ s[0] = static_cast<char>(sc.ch);
+ if (setBashOperator.Contains(sc.chNext)) {
+ s[1] = static_cast<char>(sc.chNext);
+ s[2] = '\0';
+ isCmdDelim = cmdDelimiter.InList(s);
+ if (isCmdDelim)
+ sc.Forward();
+ }
+ if (!isCmdDelim) {
+ s[1] = '\0';
+ isCmdDelim = cmdDelimiter.InList(s);
+ }
+ if (isCmdDelim) {
+ cmdState = BASH_CMD_DELIM;
+ continue;
+ }
+ }
+ // handle closing delimiters for test/arithmetic expressions - )),]],]
+ if (cmdState == BASH_CMD_ARITH && sc.Match(')', ')')) {
+ cmdState = BASH_CMD_BODY;
+ sc.Forward();
+ } else if (cmdState == BASH_CMD_TEST && IsASpace(sc.chPrev)) {
+ if (sc.Match(']', ']') && testExprType == 1) {
+ sc.Forward();
+ cmdState = BASH_CMD_BODY;
+ } else if (sc.ch == ']' && testExprType == 2) {
+ cmdState = BASH_CMD_BODY;
+ }
+ }
}
- }
+ }// sc.state
}
sc.Complete();
}
@@ -507,6 +639,14 @@ static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
levelCurrent--;
}
}
+ // Here Document folding
+ if (style == SCE_SH_HERE_DELIM) {
+ if (ch == '<' && chNext == '<') {
+ levelCurrent++;
+ }
+ } else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_PL_DEFAULT) {
+ levelCurrent--;
+ }
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
diff --git a/plugins/scintilla/scintilla/LexBasic.cxx b/plugins/scintilla/scintilla/LexBasic.cxx
index 1c5d7b4..55641ed 100644
--- a/plugins/scintilla/scintilla/LexBasic.cxx
+++ b/plugins/scintilla/scintilla/LexBasic.cxx
@@ -1,6 +1,7 @@
// Scintilla source code edit control
/** @file LexBasic.cxx
** Lexer for BlitzBasic and PureBasic.
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
**/
// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
@@ -19,18 +20,28 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
-#include <ctype.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include <string>
+#include <map>
+
+#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
@@ -86,8 +97,213 @@ static int LowerCase(int c)
return c;
}
-static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler, char comment_char) {
+static int CheckBlitzFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "function") ||
+ !strcmp(token, "type")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "end function") ||
+ !strcmp(token, "end type")) {
+ return -1;
+ }
+ return 0;
+}
+
+static int CheckPureFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "procedure") ||
+ !strcmp(token, "enumeration") ||
+ !strcmp(token, "interface") ||
+ !strcmp(token, "structure")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "endprocedure") ||
+ !strcmp(token, "endenumeration") ||
+ !strcmp(token, "endinterface") ||
+ !strcmp(token, "endstructure")) {
+ return -1;
+ }
+ return 0;
+}
+
+static int CheckFreeFoldPoint(char const *token, int &level) {
+ if (!strcmp(token, "function") ||
+ !strcmp(token, "sub") ||
+ !strcmp(token, "type")) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ return 1;
+ }
+ if (!strcmp(token, "end function") ||
+ !strcmp(token, "end sub") ||
+ !strcmp(token, "end type")) {
+ return -1;
+ }
+ return 0;
+}
+
+// An individual named option for use in an OptionSet
+
+// Options used for LexerBasic
+struct OptionsBasic {
+ bool fold;
+ bool foldSyntaxBased;
+ bool foldCommentExplicit;
+ std::string foldExplicitStart;
+ std::string foldExplicitEnd;
+ bool foldExplicitAnywhere;
+ bool foldCompact;
+ OptionsBasic() {
+ fold = false;
+ foldSyntaxBased = true;
+ foldCommentExplicit = false;
+ foldExplicitStart = "";
+ foldExplicitEnd = "";
+ foldExplicitAnywhere = false;
+ foldCompact = true;
+ }
+};
+
+static const char * const blitzbasicWordListDesc[] = {
+ "BlitzBasic Keywords",
+ "user1",
+ "user2",
+ "user3",
+ 0
+};
+
+static const char * const purebasicWordListDesc[] = {
+ "PureBasic Keywords",
+ "PureBasic PreProcessor Keywords",
+ "user defined 1",
+ "user defined 2",
+ 0
+};
+
+static const char * const freebasicWordListDesc[] = {
+ "FreeBasic Keywords",
+ "FreeBasic PreProcessor Keywords",
+ "user defined 1",
+ "user defined 2",
+ 0
+};
+
+struct OptionSetBasic : public OptionSet<OptionsBasic> {
+ OptionSetBasic(const char * const wordListDescriptions[]) {
+ DefineProperty("fold", &OptionsBasic::fold);
+
+ DefineProperty("fold.basic.syntax.based", &OptionsBasic::foldSyntaxBased,
+ "Set this property to 0 to disable syntax based folding.");
+
+ DefineProperty("fold.basic.comment.explicit", &OptionsBasic::foldCommentExplicit,
+ "This option enables folding explicit fold points when using the Basic lexer. "
+ "Explicit fold points allows adding extra folding by placing a ;{ (BB/PB) or '{ (FB) comment at the start "
+ "and a ;} (BB/PB) or '} (FB) at the end of a section that should be folded.");
+
+ DefineProperty("fold.basic.explicit.start", &OptionsBasic::foldExplicitStart,
+ "The string to use for explicit fold start points, replacing the standard ;{ (BB/PB) or '{ (FB).");
+
+ DefineProperty("fold.basic.explicit.end", &OptionsBasic::foldExplicitEnd,
+ "The string to use for explicit fold end points, replacing the standard ;} (BB/PB) or '} (FB).");
+
+ DefineProperty("fold.basic.explicit.anywhere", &OptionsBasic::foldExplicitAnywhere,
+ "Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+ DefineProperty("fold.compact", &OptionsBasic::foldCompact);
+
+ DefineWordListSets(wordListDescriptions);
+ }
+};
+
+class LexerBasic : public ILexer {
+ char comment_char;
+ int (*CheckFoldPoint)(char const *, int &);
+ WordList keywordlists[4];
+ OptionsBasic options;
+ OptionSetBasic osBasic;
+public:
+ LexerBasic(char comment_char_, int (*CheckFoldPoint_)(char const *, int &), const char * const wordListDescriptions[]) :
+ comment_char(comment_char_),
+ CheckFoldPoint(CheckFoldPoint_),
+ osBasic(wordListDescriptions) {
+ }
+ ~LexerBasic() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char * SCI_METHOD PropertyNames() {
+ return osBasic.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osBasic.PropertyType(name);
+ }
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osBasic.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osBasic.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ 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);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+ static ILexer *LexerFactoryBlitzBasic() {
+ return new LexerBasic(';', CheckBlitzFoldPoint, blitzbasicWordListDesc);
+ }
+ static ILexer *LexerFactoryPureBasic() {
+ return new LexerBasic(';', CheckPureFoldPoint, purebasicWordListDesc);
+ }
+ static ILexer *LexerFactoryFreeBasic() {
+ return new LexerBasic('\'', CheckFreeFoldPoint, freebasicWordListDesc );
+ }
+};
+
+int SCI_METHOD LexerBasic::PropertySet(const char *key, const char *val) {
+ if (osBasic.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerBasic::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywordlists[0];
+ break;
+ case 1:
+ wordListN = &keywordlists[1];
+ break;
+ case 2:
+ wordListN = &keywordlists[2];
+ break;
+ case 3:
+ wordListN = &keywordlists[3];
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerBasic::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+
bool wasfirst = true, isfirst = true; // true if first token in a line
styler.StartAt(startPos);
@@ -111,7 +327,7 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
};
sc.GetCurrentLowered(s, sizeof(s));
for (int i = 0; i < 4; i++) {
- if (keywordlists[i]->InList(s)) {
+ if (keywordlists[i].InList(s)) {
sc.ChangeState(kstates[i]);
}
}
@@ -202,66 +418,30 @@ static void ColouriseBasicDoc(unsigned int startPos, int length, int initStyle,
sc.Complete();
}
-static int CheckBlitzFoldPoint(char const *token, int &level) {
- if (!strcmp(token, "function") ||
- !strcmp(token, "type")) {
- level |= SC_FOLDLEVELHEADERFLAG;
- return 1;
- }
- if (!strcmp(token, "end function") ||
- !strcmp(token, "end type")) {
- return -1;
- }
- return 0;
-}
-static int CheckPureFoldPoint(char const *token, int &level) {
- if (!strcmp(token, "procedure") ||
- !strcmp(token, "enumeration") ||
- !strcmp(token, "interface") ||
- !strcmp(token, "structure")) {
- level |= SC_FOLDLEVELHEADERFLAG;
- return 1;
- }
- if (!strcmp(token, "endprocedure") ||
- !strcmp(token, "endenumeration") ||
- !strcmp(token, "endinterface") ||
- !strcmp(token, "endstructure")) {
- return -1;
- }
- return 0;
-}
+void SCI_METHOD LexerBasic::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
-static int CheckFreeFoldPoint(char const *token, int &level) {
- if (!strcmp(token, "function") ||
- !strcmp(token, "sub") ||
- !strcmp(token, "type")) {
- level |= SC_FOLDLEVELHEADERFLAG;
- return 1;
- }
- if (!strcmp(token, "end function") ||
- !strcmp(token, "end sub") ||
- !strcmp(token, "end type")) {
- return -1;
- }
- return 0;
-}
+ if (!options.fold)
+ return;
+
+ LexAccessor styler(pAccess);
-static void FoldBasicDoc(unsigned int startPos, int length,
- Accessor &styler, int (*CheckFoldPoint)(char const *, int &)) {
int line = styler.GetLine(startPos);
int level = styler.LevelAt(line);
int go = 0, done = 0;
int endPos = startPos + length;
char word[256];
int wordlen = 0;
- int i;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
+ const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
+ int cNext = styler[startPos];
+
// Scan for tokens at the start of the line (they may include
// whitespace, for tokens like "End Function"
- for (i = startPos; i < endPos; i++) {
- int c = styler.SafeGetCharAt(i);
- if (!done && !go) {
+ for (int i = startPos; i < endPos; i++) {
+ int c = cNext;
+ cNext = styler.SafeGetCharAt(i + 1);
+ bool atEOL = (c == '\r' && cNext != '\n') || (c == '\n');
+ if (options.foldSyntaxBased && !done && !go) {
if (wordlen) { // are we scanning a token already?
word[wordlen] = static_cast<char>(LowerCase(c));
if (!IsIdentifier(c)) { // done with token
@@ -291,8 +471,27 @@ static void FoldBasicDoc(unsigned int startPos, int length,
}
}
}
- if (c == '\n') { // line end
- if (!done && wordlen == 0 && foldCompact) // line was only space
+ if (options.foldCommentExplicit && ((styler.StyleAt(i) == SCE_B_COMMENT) || options.foldExplicitAnywhere)) {
+ if (userDefinedFoldMarkers) {
+ if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ go = 1;
+ } else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ go = -1;
+ }
+ } else {
+ if (c == comment_char) {
+ if (cNext == '{') {
+ level |= SC_FOLDLEVELHEADERFLAG;
+ go = 1;
+ } else if (cNext == '}') {
+ go = -1;
+ }
+ }
+ }
+ }
+ if (atEOL) { // line end
+ if (!done && wordlen == 0 && options.foldCompact) // line was only space
level |= SC_FOLDLEVELWHITEFLAG;
if (level != styler.LevelAt(line))
styler.SetLevel(line, level);
@@ -308,66 +507,8 @@ static void FoldBasicDoc(unsigned int startPos, int length,
}
}
-static void ColouriseBlitzBasicDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
-}
-
-static void ColourisePureBasicDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, ';');
-}
-
-static void ColouriseFreeBasicDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
- ColouriseBasicDoc(startPos, length, initStyle, keywordlists, styler, '\'');
-}
-
-static void FoldBlitzBasicDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
- FoldBasicDoc(startPos, length, styler, CheckBlitzFoldPoint);
-}
-
-static void FoldPureBasicDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
- FoldBasicDoc(startPos, length, styler, CheckPureFoldPoint);
-}
-
-static void FoldFreeBasicDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
- FoldBasicDoc(startPos, length, styler, CheckFreeFoldPoint);
-}
-
-static const char * const blitzbasicWordListDesc[] = {
- "BlitzBasic Keywords",
- "user1",
- "user2",
- "user3",
- 0
-};
-
-static const char * const purebasicWordListDesc[] = {
- "PureBasic Keywords",
- "PureBasic PreProcessor Keywords",
- "user defined 1",
- "user defined 2",
- 0
-};
-
-static const char * const freebasicWordListDesc[] = {
- "FreeBasic Keywords",
- "FreeBasic PreProcessor Keywords",
- "user defined 1",
- "user defined 2",
- 0
-};
-
-LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, ColouriseBlitzBasicDoc, "blitzbasic",
- FoldBlitzBasicDoc, blitzbasicWordListDesc);
-
-LexerModule lmPureBasic(SCLEX_PUREBASIC, ColourisePureBasicDoc, "purebasic",
- FoldPureBasicDoc, purebasicWordListDesc);
+LexerModule lmBlitzBasic(SCLEX_BLITZBASIC, LexerBasic::LexerFactoryBlitzBasic, "blitzbasic", blitzbasicWordListDesc);
-LexerModule lmFreeBasic(SCLEX_FREEBASIC, ColouriseFreeBasicDoc, "freebasic",
- FoldFreeBasicDoc, freebasicWordListDesc);
+LexerModule lmPureBasic(SCLEX_PUREBASIC, LexerBasic::LexerFactoryPureBasic, "purebasic", purebasicWordListDesc);
+LexerModule lmFreeBasic(SCLEX_FREEBASIC, LexerBasic::LexerFactoryFreeBasic, "freebasic", freebasicWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexBullant.cxx b/plugins/scintilla/scintilla/LexBullant.cxx
index cc60cd2..bb5c9c4 100644
--- a/plugins/scintilla/scintilla/LexBullant.cxx
+++ b/plugins/scintilla/scintilla/LexBullant.cxx
@@ -3,24 +3,29 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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 int classifyWordBullant(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler) {
char s[100];
+ s[0] = '\0';
for (unsigned int i = 0; i < end - start + 1 && i < 30; i++) {
s[i] = static_cast<char>(tolower(styler[start + i]));
s[i + 1] = '\0';
@@ -111,7 +116,7 @@ static void ColouriseBullantDoc(unsigned int startPos, int length, int initStyle
}
blockChange=0;
*/ }
- if (!isspace(ch))
+ if (!(isascii(ch) && isspace(ch)))
visibleChars++;
if (styler.IsLeadByte(ch)) {
diff --git a/plugins/scintilla/scintilla/LexCLW.cxx b/plugins/scintilla/scintilla/LexCLW.cxx
index 624ef0f..c1dea60 100644
--- a/plugins/scintilla/scintilla/LexCLW.cxx
+++ b/plugins/scintilla/scintilla/LexCLW.cxx
@@ -10,16 +10,19 @@
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -60,10 +63,10 @@ inline bool IsALabelStart(const int iChar) {
// Is a label character
inline bool IsALabelCharacter(const int iChar) {
- return(isalnum(iChar) || iChar == '_' || iChar == ':');
+ return(isalnum(iChar) || iChar == '_' || iChar == ':');
}
-// Is the character is a ! and the the next character is not a !
+// Is the character is a ! and the the next character is not a !
inline bool IsACommentStart(const int iChar) {
return(iChar == '!');
@@ -126,7 +129,7 @@ inline bool SetNumericConstantState(StyleContext &scDoc) {
break;
default :
break;
- }
+ }
}
// If points found (can be more than one for improper formatted number
if (iPoints > 0) {
@@ -186,12 +189,12 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
WordList &wlLabelReservedWords = *wlKeywords[7]; // Clarion Reserved Keywords (Labels)
WordList &wlProcLabelReservedWords = *wlKeywords[8]; // Clarion Reserved Keywords (Procedure Labels)
- const char wlProcReservedKeywordList[] =
+ const char wlProcReservedKeywordList[] =
"PROCEDURE FUNCTION";
WordList wlProcReservedKeywords;
wlProcReservedKeywords.Set(wlProcReservedKeywordList);
- const char wlCompilerKeywordList[] =
+ const char wlCompilerKeywordList[] =
"COMPILE OMIT";
WordList wlCompilerKeywords;
wlCompilerKeywords.Set(wlCompilerKeywordList);
@@ -243,7 +246,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
// change the label to error state
scDoc.ChangeState(SCE_CLW_ERROR);
}
- // Else if UPPERCASE label string is
+ // Else if UPPERCASE label string is
else if (wlProcLabelReservedWords.InList(cLabel) && iColumn1Label) {
char cWord[512]; // Word buffer
// Get the next word from the current position
@@ -368,13 +371,13 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
// Increment the parenthese level
iParenthesesLevel++;
}
- // Else if the character is a ) (close parenthese)
+ // Else if the character is a ) (close parenthese)
else if (scDoc.ch == ')') {
// If the parenthese level is set to zero
// parentheses matched
if (!iParenthesesLevel) {
scDoc.SetState(SCE_CLW_DEFAULT);
- }
+ }
// Else parenthese level is greater than zero
// still looking for matching parentheses
else {
@@ -399,7 +402,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
|| IsAHexCharacter(scDoc.ch, bCaseSensitive)
|| scDoc.ch == '.'
|| IsANumericBaseCharacter(scDoc.ch, bCaseSensitive))) {
- // If the number was a real
+ // If the number was a real
if (SetNumericConstantState(scDoc)) {
// Colour the matched string to the real constant state
scDoc.ChangeState(SCE_CLW_REAL_CONSTANT);
@@ -461,7 +464,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
}
// Default Handling
else {
- // If in default state
+ // If in default state
if (scDoc.state == SCE_CLW_DEFAULT) {
// If is a letter could be a possible statement
if (isalpha(scDoc.ch)) {
@@ -477,10 +480,10 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
else if (IsACommentStart(scDoc.ch) || scDoc.ch == '|') {
// then set the state to comment.
scDoc.SetState(SCE_CLW_COMMENT);
- }
+ }
// else if the character is a ' (single quote)
else if (scDoc.ch == '\'') {
- // If the character is also a ' (single quote)
+ // If the character is also a ' (single quote)
// Embedded Apostrophe
if (scDoc.chNext == '\'') {
// Move forward colouring it as default state
@@ -490,7 +493,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
// move to the next character and then set the state to comment.
scDoc.ForwardSetState(SCE_CLW_STRING);
}
- }
+ }
// else the character is an @ (ampersand)
else if (scDoc.ch == '@') {
// Case insensitive.
@@ -509,7 +512,7 @@ static void ColouriseClarionDoc(unsigned int uiStartPos, int iLength, int iInitS
scDoc.SetState(SCE_CLW_PICTURE_STRING);
}
}
- }
+ }
}
}
}
@@ -616,7 +619,7 @@ static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle,
iStyle = iStyleNext;
iStyleNext = accStyler.StyleAt(uiPos + 1);
bool bEOL = (chChar == '\r' && chNext != '\n') || (chChar == '\n');
-
+
if (iStylePrev == SCE_CLW_DEFAULT) {
if (iStyle == SCE_CLW_KEYWORD || iStyle == SCE_CLW_STRUCTURE_DATA_TYPE) {
// Store last word start point.
@@ -647,7 +650,7 @@ static void FoldClarionDoc(unsigned int uiStartPos, int iLength, int iInitStyle,
iLevelPrev = iLevelCurrent;
iVisibleChars = 0;
}
-
+
if (!isspacechar(chChar))
iVisibleChars++;
}
diff --git a/plugins/scintilla/scintilla/LexCOBOL.cxx b/plugins/scintilla/scintilla/LexCOBOL.cxx
index d061d5c..a9a8f55 100644
--- a/plugins/scintilla/scintilla/LexCOBOL.cxx
+++ b/plugins/scintilla/scintilla/LexCOBOL.cxx
@@ -10,18 +10,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
@@ -90,11 +93,11 @@ static int classifyWordCOBOL(unsigned int start, unsigned int end, /*WordList &k
getRange(start, end, styler, s, sizeof(s));
char chAttr = SCE_C_IDENTIFIER;
- if (isdigit(s[0]) || (s[0] == '.')) {
+ if (isdigit(s[0]) || (s[0] == '.') || (s[0] == 'v')) {
chAttr = SCE_C_NUMBER;
char *p = s + 1;
while (*p) {
- if (!isdigit(*p) && isCOBOLwordchar(*p)) {
+ if ((!isdigit(*p) && (*p) != 'v') && isCOBOLwordchar(*p)) {
chAttr = SCE_C_IDENTIFIER;
break;
}
@@ -202,7 +205,7 @@ static void ColouriseCOBOLDoc(unsigned int startPos, int length, int initStyle,
}
if (state == SCE_C_DEFAULT) {
- if (isCOBOLwordstart(ch) || (ch == '$' && isalpha(chNext))) {
+ if (isCOBOLwordstart(ch) || (ch == '$' && isascii(chNext) && isalpha(chNext))) {
ColourTo(styler, i-1, state);
state = SCE_C_IDENTIFIER;
} else if (column == 0 && ch == '*' && chNext != '*') {
diff --git a/plugins/scintilla/scintilla/LexCPP.cxx b/plugins/scintilla/scintilla/LexCPP.cxx
index 9577afb..22477c3 100644
--- a/plugins/scintilla/scintilla/LexCPP.cxx
+++ b/plugins/scintilla/scintilla/LexCPP.cxx
@@ -1,6 +1,7 @@
// Scintilla source code edit control
/** @file LexCPP.cxx
** Lexer for C++, C, Java, and JavaScript.
+ ** Further folding features and configuration properties added by "Udo Lechner" <dlchnr(at)gmx(dot)net>
**/
// Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
@@ -10,16 +11,29 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
-#include "Platform.h"
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#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"
+#include "OptionSet.h"
+#include "SparseState.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -39,7 +53,7 @@ static bool IsSpaceEquiv(int state) {
// a = b+++/ptn/...
// Putting a space between the '++' post-inc operator and the '+' binary op
// fixes this, and is highly recommended for readability anyway.
-static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
+static bool FollowsPostfixOperator(StyleContext &sc, LexAccessor &styler) {
int pos = (int) sc.currentPos;
while (--pos > 0) {
char ch = styler[pos];
@@ -50,18 +64,384 @@ static bool FollowsPostfixOperator(StyleContext &sc, Accessor &styler) {
return false;
}
-static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler, bool caseSensitive) {
+static bool followsReturnKeyword(StyleContext &sc, LexAccessor &styler) {
+ // Don't look at styles, so no need to flush.
+ int pos = (int) sc.currentPos;
+ int currentLine = styler.GetLine(pos);
+ int lineStartPos = styler.LineStart(currentLine);
+ char ch;
+ while (--pos > lineStartPos) {
+ ch = styler.SafeGetCharAt(pos);
+ if (ch != ' ' && ch != '\t') {
+ break;
+ }
+ }
+ const char *retBack = "nruter";
+ const char *s = retBack;
+ while (*s
+ && pos >= lineStartPos
+ && styler.SafeGetCharAt(pos) == *s) {
+ s++;
+ pos--;
+ }
+ return !*s;
+}
+
+static std::string GetRestOfLine(LexAccessor &styler, int start, bool allowSpace) {
+ std::string restOfLine;
+ int i =0;
+ char ch = styler.SafeGetCharAt(start + i, '\n');
+ while ((ch != '\r') && (ch != '\n')) {
+ if (allowSpace || (ch != ' '))
+ restOfLine += ch;
+ i++;
+ ch = styler.SafeGetCharAt(start + i, '\n');
+ }
+ return restOfLine;
+}
+
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_C_COMMENT ||
+ style == SCE_C_COMMENTDOC ||
+ style == SCE_C_COMMENTDOCKEYWORD ||
+ style == SCE_C_COMMENTDOCKEYWORDERROR;
+}
+
+static std::vector<std::string> Tokenize(const std::string &s) {
+ // Break into space separated tokens
+ std::string word;
+ std::vector<std::string> tokens;
+ for (const char *cp = s.c_str(); *cp; cp++) {
+ if ((*cp == ' ') || (*cp == '\t')) {
+ if (!word.empty()) {
+ tokens.push_back(word);
+ word = "";
+ }
+ } else {
+ word += *cp;
+ }
+ }
+ if (!word.empty()) {
+ tokens.push_back(word);
+ }
+ return tokens;
+}
+
+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_) {
+ }
+};
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2];
- WordList &keywords4 = *keywordlists[3];
+class LinePPState {
+ int state;
+ int ifTaken;
+ int level;
+ bool ValidLevel() const {
+ return level >= 0 && level < 32;
+ }
+ int maskLevel() const {
+ return 1 << level;
+ }
+public:
+ LinePPState() : state(0), ifTaken(0), level(-1) {
+ }
+ bool IsInactive() const {
+ return state != 0;
+ }
+ bool CurrentIfTaken() {
+ return (ifTaken & maskLevel()) != 0;
+ }
+ void StartSection(bool on) {
+ level++;
+ if (ValidLevel()) {
+ if (on) {
+ state &= ~maskLevel();
+ ifTaken |= maskLevel();
+ } else {
+ state |= maskLevel();
+ ifTaken &= ~maskLevel();
+ }
+ }
+ }
+ void EndSection() {
+ if (ValidLevel()) {
+ state &= ~maskLevel();
+ ifTaken &= ~maskLevel();
+ }
+ level--;
+ }
+ void InvertCurrentLevel() {
+ if (ValidLevel()) {
+ state ^= maskLevel();
+ ifTaken |= maskLevel();
+ }
+ }
+};
+
+// Hold the preprocessor state for each line seen.
+// Currently one entry per line but could become sparse with just one entry per preprocessor line.
+class PPStates {
+ std::vector<LinePPState> vlls;
+public:
+ LinePPState ForLine(int line) {
+ if ((line > 0) && (vlls.size() > static_cast<size_t>(line))) {
+ return vlls[line];
+ } else {
+ return LinePPState();
+ }
+ }
+ void Add(int line, LinePPState lls) {
+ vlls.resize(line+1);
+ vlls[line] = lls;
+ }
+};
- // property styling.within.preprocessor
- // For C++ code, determines whether all preprocessor code is styled in the preprocessor style (0, the default)
- // or only from the initial # to the end of the command word(1).
- bool stylingWithinPreprocessor = styler.GetPropertyInt("styling.within.preprocessor") != 0;
+// An individual named option for use in an OptionSet
+
+// Options used for LexerCPP
+struct OptionsCPP {
+ bool stylingWithinPreprocessor;
+ bool identifiersAllowDollars;
+ bool trackPreprocessor;
+ bool updatePreprocessor;
+ bool triplequotedStrings;
+ bool fold;
+ bool foldSyntaxBased;
+ bool foldComment;
+ bool foldCommentMultiline;
+ bool foldCommentExplicit;
+ std::string foldExplicitStart;
+ std::string foldExplicitEnd;
+ bool foldExplicitAnywhere;
+ bool foldPreprocessor;
+ bool foldCompact;
+ bool foldAtElse;
+ OptionsCPP() {
+ stylingWithinPreprocessor = false;
+ identifiersAllowDollars = true;
+ trackPreprocessor = true;
+ updatePreprocessor = true;
+ triplequotedStrings = false;
+ fold = false;
+ foldSyntaxBased = true;
+ foldComment = false;
+ foldCommentMultiline = true;
+ foldCommentExplicit = true;
+ foldExplicitStart = "";
+ foldExplicitEnd = "";
+ foldExplicitAnywhere = false;
+ foldPreprocessor = false;
+ foldCompact = false;
+ foldAtElse = false;
+ }
+};
+
+static const char *const cppWordLists[] = {
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ "Documentation comment keywords",
+ "Global classes and typedefs",
+ "Preprocessor definitions",
+ 0,
+};
+
+struct OptionSetCPP : public OptionSet<OptionsCPP> {
+ OptionSetCPP() {
+ DefineProperty("styling.within.preprocessor", &OptionsCPP::stylingWithinPreprocessor,
+ "For C++ code, determines whether all preprocessor code is styled in the "
+ "preprocessor style (0, the default) or only from the initial # to the end "
+ "of the command word(1).");
+
+ DefineProperty("lexer.cpp.allow.dollars", &OptionsCPP::identifiersAllowDollars,
+ "Set to 0 to disallow the '$' character in identifiers with the cpp lexer.");
+
+ DefineProperty("lexer.cpp.track.preprocessor", &OptionsCPP::trackPreprocessor,
+ "Set to 1 to interpret #if/#else/#endif to grey out code that is not active.");
+
+ DefineProperty("lexer.cpp.update.preprocessor", &OptionsCPP::updatePreprocessor,
+ "Set to 1 to update preprocessor definitions when #define found.");
+
+ DefineProperty("lexer.cpp.triplequoted.strings", &OptionsCPP::triplequotedStrings,
+ "Set to 1 to enable highlighting of triple-quoted strings.");
+
+ DefineProperty("fold", &OptionsCPP::fold);
+
+ DefineProperty("fold.cpp.syntax.based", &OptionsCPP::foldSyntaxBased,
+ "Set this property to 0 to disable syntax based folding.");
+
+ DefineProperty("fold.comment", &OptionsCPP::foldComment,
+ "This option enables folding multi-line comments and explicit fold points when using the C++ lexer. "
+ "Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //} "
+ "at the end of a section that should fold.");
+
+ DefineProperty("fold.cpp.comment.multiline", &OptionsCPP::foldCommentMultiline,
+ "Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
+
+ DefineProperty("fold.cpp.comment.explicit", &OptionsCPP::foldCommentExplicit,
+ "Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
+
+ DefineProperty("fold.cpp.explicit.start", &OptionsCPP::foldExplicitStart,
+ "The string to use for explicit fold start points, replacing the standard //{.");
+
+ DefineProperty("fold.cpp.explicit.end", &OptionsCPP::foldExplicitEnd,
+ "The string to use for explicit fold end points, replacing the standard //}.");
+
+ DefineProperty("fold.cpp.explicit.anywhere", &OptionsCPP::foldExplicitAnywhere,
+ "Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+ DefineProperty("fold.preprocessor", &OptionsCPP::foldPreprocessor,
+ "This option enables folding preprocessor directives when using the C++ lexer. "
+ "Includes C#'s explicit #region and #endregion folding directives.");
+
+ DefineProperty("fold.compact", &OptionsCPP::foldCompact);
+
+ DefineProperty("fold.at.else", &OptionsCPP::foldAtElse,
+ "This option enables C++ folding on a \"} else {\" line of an if statement.");
+
+ DefineWordListSets(cppWordLists);
+ }
+};
+
+class LexerCPP : public ILexer {
+ bool caseSensitive;
+ CharacterSet setWord;
+ CharacterSet setNegationOp;
+ CharacterSet setArithmethicOp;
+ CharacterSet setRelOp;
+ CharacterSet setLogicalOp;
+ PPStates vlls;
+ std::vector<PPDefinition> ppDefineHistory;
+ WordList keywords;
+ WordList keywords2;
+ WordList keywords3;
+ WordList keywords4;
+ WordList ppDefinitions;
+ std::map<std::string, std::string> preprocessorDefinitionsStart;
+ OptionsCPP options;
+ OptionSetCPP osCPP;
+ SparseState<std::string> rawStringTerminators;
+ enum { activeFlag = 0x40 };
+public:
+ LexerCPP(bool caseSensitive_) :
+ caseSensitive(caseSensitive_),
+ setWord(CharacterSet::setAlphaNum, "._", 0x80, true),
+ setNegationOp(CharacterSet::setNone, "!"),
+ setArithmethicOp(CharacterSet::setNone, "+-/*%"),
+ setRelOp(CharacterSet::setNone, "=!<>"),
+ setLogicalOp(CharacterSet::setNone, "|&") {
+ }
+ ~LexerCPP() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char * SCI_METHOD PropertyNames() {
+ return osCPP.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osCPP.PropertyType(name);
+ }
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osCPP.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osCPP.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ 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);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactoryCPP() {
+ return new LexerCPP(true);
+ }
+ static ILexer *LexerFactoryCPPInsensitive() {
+ return new LexerCPP(false);
+ }
+ static int MaskActive(int style) {
+ return style & ~activeFlag;
+ }
+ void EvaluateTokens(std::vector<std::string> &tokens);
+ bool EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions);
+};
+
+int SCI_METHOD LexerCPP::PropertySet(const char *key, const char *val) {
+ if (osCPP.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerCPP::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywords;
+ break;
+ case 1:
+ wordListN = &keywords2;
+ break;
+ case 2:
+ wordListN = &keywords3;
+ break;
+ case 3:
+ wordListN = &keywords4;
+ break;
+ case 4:
+ wordListN = &ppDefinitions;
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ if (n == 4) {
+ // Rebuild preprocessorDefinitions
+ preprocessorDefinitionsStart.clear();
+ for (int nDefinition = 0; nDefinition < ppDefinitions.len; nDefinition++) {
+ char *cpDefinition = ppDefinitions.words[nDefinition];
+ char *cpEquals = strchr(cpDefinition, '=');
+ if (cpEquals) {
+ std::string name(cpDefinition, cpEquals - cpDefinition);
+ std::string val(cpEquals+1);
+ preprocessorDefinitionsStart[name] = val;
+ } else {
+ std::string name(cpDefinition);
+ std::string val("1");
+ preprocessorDefinitionsStart[name] = val;
+ }
+ }
+ }
+ }
+ }
+ return firstModification;
+}
+
+// Functor used to truncate history
+struct After {
+ int line;
+ After(int line_) : line(line_) {}
+ bool operator()(PPDefinition &p) const {
+ return p.line > line;
+ }
+};
+
+void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
CharacterSet setOKBeforeRE(CharacterSet::setNone, "([{=,:;!%^&*|?~+-");
CharacterSet setCouldBePostOp(CharacterSet::setNone, "+-");
@@ -69,11 +449,8 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
CharacterSet setDoxygen(CharacterSet::setAlpha, "$ \\&<>#{}[]");
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
- CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
- // property lexer.cpp.allow.dollars
- // Set to 0 to disallow the '$' character in identifiers with the cpp lexer.
- if (styler.GetPropertyInt("lexer.cpp.allow.dollars", 1) != 0) {
+ if (options.identifiersAllowDollars) {
setWordStart.Add('$');
setWord.Add('$');
}
@@ -85,9 +462,11 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
bool continuationLine = false;
bool isIncludePreprocessor = false;
- if (initStyle == SCE_C_PREPROCESSOR) {
+ int lineCurrent = styler.GetLine(startPos);
+ if ((initStyle == SCE_C_PREPROCESSOR) ||
+ (initStyle == SCE_C_COMMENTLINE) ||
+ (initStyle == SCE_C_COMMENTLINEDOC)) {
// Set continuationLine if last character of previous line is '\'
- int lineCurrent = styler.GetLine(startPos);
if (lineCurrent > 0) {
int chBack = styler.SafeGetCharAt(startPos-1, 0);
int chBack2 = styler.SafeGetCharAt(startPos-2, 0);
@@ -111,21 +490,64 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
}
}
- StyleContext sc(startPos, length, initStyle, styler);
+ StyleContext sc(startPos, length, initStyle, styler, 0x7f);
+ LinePPState preproc = vlls.ForLine(lineCurrent);
+
+ bool definitionsChanged = false;
+
+ // Truncate ppDefineHistory before current line
+
+ if (!options.updatePreprocessor)
+ ppDefineHistory.clear();
+
+ std::vector<PPDefinition>::iterator itInvalid = std::find_if(ppDefineHistory.begin(), ppDefineHistory.end(), After(lineCurrent-1));
+ if (itInvalid != ppDefineHistory.end()) {
+ ppDefineHistory.erase(itInvalid, ppDefineHistory.end());
+ definitionsChanged = true;
+ }
+
+ 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;
+ }
+
+ std::string rawStringTerminator = rawStringTerminators.ValueAt(lineCurrent-1);
+ SparseState<std::string> rawSTNew(lineCurrent);
+
+ int activitySet = preproc.IsInactive() ? activeFlag : 0;
for (; sc.More(); sc.Forward()) {
if (sc.atLineStart) {
- if (sc.state == SCE_C_STRING) {
+ if ((sc.state == SCE_C_STRING) || (sc.state == SCE_C_CHARACTER)) {
// Prevent SCE_C_STRINGEOL from leaking back to previous line which
// ends with a line continuation by locking in the state upto this position.
- sc.SetState(SCE_C_STRING);
+ sc.SetState(sc.state);
}
// Reset states to begining of colourise so no surprises
// if different sets of lines lexed.
visibleChars = 0;
lastWordWasUUID = false;
isIncludePreprocessor = false;
+ if (preproc.IsInactive()) {
+ activitySet = activeFlag;
+ sc.SetState(sc.state | activitySet);
+ }
+ if (activitySet) {
+ if (sc.ch == '#') {
+ if (sc.Match("#else") || sc.Match("#end") || sc.Match("#if")) {
+ //activitySet = 0;
+ }
+ }
+ }
+ }
+
+ if (sc.atLineEnd) {
+ lineCurrent++;
+ vlls.Add(lineCurrent, preproc);
+ if (rawStringTerminator != "") {
+ rawSTNew.Set(lineCurrent-1, rawStringTerminator);
+ }
}
// Handle line continuation generically.
@@ -140,15 +562,17 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
}
}
+ const bool atLineEndBeforeSwitch = sc.atLineEnd;
+
// Determine if the current state should terminate.
- switch (sc.state) {
+ switch (MaskActive(sc.state)) {
case SCE_C_OPERATOR:
- sc.SetState(SCE_C_DEFAULT);
+ sc.SetState(SCE_C_DEFAULT|activitySet);
break;
case SCE_C_NUMBER:
// We accept almost anything because of hex. and number suffixes
- if (!setWord.Contains(sc.ch)) {
- sc.SetState(SCE_C_DEFAULT);
+ if (!(setWord.Contains(sc.ch) || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
}
break;
case SCE_C_IDENTIFIER:
@@ -161,59 +585,76 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
}
if (keywords.InList(s)) {
lastWordWasUUID = strcmp(s, "uuid") == 0;
- sc.ChangeState(SCE_C_WORD);
+ sc.ChangeState(SCE_C_WORD|activitySet);
} else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_C_WORD2);
+ sc.ChangeState(SCE_C_WORD2|activitySet);
} else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_C_GLOBALCLASS);
+ sc.ChangeState(SCE_C_GLOBALCLASS|activitySet);
+ }
+ const bool literalString = sc.ch == '\"';
+ if (literalString || sc.ch == '\'') {
+ size_t lenS = strlen(s);
+ const bool raw = literalString && sc.chPrev == 'R';
+ if (raw)
+ s[lenS--] = '\0';
+ bool valid =
+ (lenS == 0) ||
+ ((lenS == 1) && ((s[0] == 'L') || (s[0] == 'u') || (s[0] == 'U'))) ||
+ ((lenS == 2) && literalString && (s[0] == 'u') && (s[1] == '8'));
+ if (valid) {
+ if (literalString)
+ sc.ChangeState((raw ? SCE_C_STRINGRAW : SCE_C_STRING)|activitySet);
+ else
+ sc.ChangeState(SCE_C_CHARACTER|activitySet);
+ }
}
- sc.SetState(SCE_C_DEFAULT);
+ sc.SetState(SCE_C_DEFAULT|activitySet);
}
break;
case SCE_C_PREPROCESSOR:
if (sc.atLineStart && !continuationLine) {
- sc.SetState(SCE_C_DEFAULT);
- } else if (stylingWithinPreprocessor) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ } else if (options.stylingWithinPreprocessor) {
if (IsASpace(sc.ch)) {
- sc.SetState(SCE_C_DEFAULT);
+ sc.SetState(SCE_C_DEFAULT|activitySet);
}
} else {
if (sc.Match('/', '*') || sc.Match('/', '/')) {
- sc.SetState(SCE_C_DEFAULT);
+ sc.SetState(SCE_C_DEFAULT|activitySet);
}
}
break;
case SCE_C_COMMENT:
if (sc.Match('*', '/')) {
sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
}
break;
case SCE_C_COMMENTDOC:
if (sc.Match('*', '/')) {
sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
// Verify that we have the conditions to mark a comment-doc-keyword
if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
styleBeforeDCKeyword = SCE_C_COMMENTDOC;
- sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);
}
}
break;
case SCE_C_COMMENTLINE:
- if (sc.atLineStart) {
- sc.SetState(SCE_C_DEFAULT);
+ if (sc.atLineStart && !continuationLine) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
}
break;
case SCE_C_COMMENTLINEDOC:
- if (sc.atLineStart) {
- sc.SetState(SCE_C_DEFAULT);
+ if (sc.atLineStart && !continuationLine) {
+ sc.SetState(SCE_C_DEFAULT|activitySet);
} else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
// Verify that we have the conditions to mark a comment-doc-keyword
if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
styleBeforeDCKeyword = SCE_C_COMMENTLINEDOC;
- sc.SetState(SCE_C_COMMENTDOCKEYWORD);
+ sc.SetState(SCE_C_COMMENTDOCKEYWORD|activitySet);
}
}
break;
@@ -221,7 +662,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
if ((styleBeforeDCKeyword == SCE_C_COMMENTDOC) && sc.Match('*', '/')) {
sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
sc.Forward();
- sc.ForwardSetState(SCE_C_DEFAULT);
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
} else if (!setDoxygen.Contains(sc.ch)) {
char s[100];
if (caseSensitive) {
@@ -230,17 +671,17 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
sc.GetCurrentLowered(s, sizeof(s));
}
if (!IsASpace(sc.ch) || !keywords3.InList(s + 1)) {
- sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR);
+ sc.ChangeState(SCE_C_COMMENTDOCKEYWORDERROR|activitySet);
}
sc.SetState(styleBeforeDCKeyword);
}
break;
case SCE_C_STRING:
if (sc.atLineEnd) {
- sc.ChangeState(SCE_C_STRINGEOL);
+ sc.ChangeState(SCE_C_STRINGEOL|activitySet);
} else if (isIncludePreprocessor) {
if (sc.ch == '>') {
- sc.ForwardSetState(SCE_C_DEFAULT);
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
isIncludePreprocessor = false;
}
} else if (sc.ch == '\\') {
@@ -248,28 +689,36 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
sc.Forward();
}
} else if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_C_DEFAULT);
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
+ case SCE_C_STRINGRAW:
+ if (sc.Match(rawStringTerminator.c_str())) {
+ for (size_t termPos=rawStringTerminator.size(); termPos; termPos--)
+ sc.Forward();
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ rawStringTerminator = "";
}
break;
case SCE_C_CHARACTER:
if (sc.atLineEnd) {
- sc.ChangeState(SCE_C_STRINGEOL);
+ sc.ChangeState(SCE_C_STRINGEOL|activitySet);
} else if (sc.ch == '\\') {
if (sc.chNext == '\"' || sc.chNext == '\'' || sc.chNext == '\\') {
sc.Forward();
}
} else if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_C_DEFAULT);
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
}
break;
case SCE_C_REGEX:
if (sc.atLineStart) {
- sc.SetState(SCE_C_DEFAULT);
+ sc.SetState(SCE_C_DEFAULT|activitySet);
} else if (sc.ch == '/') {
sc.Forward();
while ((sc.ch < 0x80) && islower(sc.ch))
sc.Forward(); // gobble regex flags
- sc.SetState(SCE_C_DEFAULT);
+ sc.SetState(SCE_C_DEFAULT|activitySet);
} else if (sc.ch == '\\') {
// Gobble up the quoted character
if (sc.chNext == '\\' || sc.chNext == '/') {
@@ -279,7 +728,7 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
break;
case SCE_C_STRINGEOL:
if (sc.atLineStart) {
- sc.SetState(SCE_C_DEFAULT);
+ sc.SetState(SCE_C_DEFAULT|activitySet);
}
break;
case SCE_C_VERBATIM:
@@ -287,72 +736,170 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
if (sc.chNext == '\"') {
sc.Forward();
} else {
- sc.ForwardSetState(SCE_C_DEFAULT);
+ sc.ForwardSetState(SCE_C_DEFAULT|activitySet);
}
}
break;
+ case SCE_C_TRIPLEVERBATIM:
+ if (sc.Match("\"\"\"")) {
+ while (sc.Match('"')) {
+ sc.Forward();
+ }
+ sc.SetState(SCE_C_DEFAULT|activitySet);
+ }
+ break;
case SCE_C_UUID:
if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ')') {
- sc.SetState(SCE_C_DEFAULT);
+ sc.SetState(SCE_C_DEFAULT|activitySet);
}
}
+ if (sc.atLineEnd && !atLineEndBeforeSwitch) {
+ // State exit processing consumed characters up to end of line.
+ lineCurrent++;
+ vlls.Add(lineCurrent, preproc);
+ }
+
// Determine if a new state should be entered.
- if (sc.state == SCE_C_DEFAULT) {
+ if (MaskActive(sc.state) == SCE_C_DEFAULT) {
if (sc.Match('@', '\"')) {
- sc.SetState(SCE_C_VERBATIM);
+ sc.SetState(SCE_C_VERBATIM|activitySet);
sc.Forward();
+ } else if (options.triplequotedStrings && sc.Match("\"\"\"")) {
+ sc.SetState(SCE_C_TRIPLEVERBATIM|activitySet);
+ sc.Forward(2);
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
if (lastWordWasUUID) {
- sc.SetState(SCE_C_UUID);
+ sc.SetState(SCE_C_UUID|activitySet);
lastWordWasUUID = false;
} else {
- sc.SetState(SCE_C_NUMBER);
+ sc.SetState(SCE_C_NUMBER|activitySet);
}
} else if (setWordStart.Contains(sc.ch) || (sc.ch == '@')) {
if (lastWordWasUUID) {
- sc.SetState(SCE_C_UUID);
+ sc.SetState(SCE_C_UUID|activitySet);
lastWordWasUUID = false;
} else {
- sc.SetState(SCE_C_IDENTIFIER);
+ sc.SetState(SCE_C_IDENTIFIER|activitySet);
}
} else if (sc.Match('/', '*')) {
if (sc.Match("/**") || sc.Match("/*!")) { // Support of Qt/Doxygen doc. style
- sc.SetState(SCE_C_COMMENTDOC);
+ sc.SetState(SCE_C_COMMENTDOC|activitySet);
} else {
- sc.SetState(SCE_C_COMMENT);
+ sc.SetState(SCE_C_COMMENT|activitySet);
}
sc.Forward(); // Eat the * so it isn't used for the end of the comment
} else if (sc.Match('/', '/')) {
if ((sc.Match("///") && !sc.Match("////")) || sc.Match("//!"))
// Support of Qt/Doxygen doc. style
- sc.SetState(SCE_C_COMMENTLINEDOC);
+ sc.SetState(SCE_C_COMMENTLINEDOC|activitySet);
else
- sc.SetState(SCE_C_COMMENTLINE);
- } else if (sc.ch == '/' && setOKBeforeRE.Contains(chPrevNonWhite) &&
- (!setCouldBePostOp.Contains(chPrevNonWhite) || !FollowsPostfixOperator(sc, styler))) {
- sc.SetState(SCE_C_REGEX); // JavaScript's RegEx
+ sc.SetState(SCE_C_COMMENTLINE|activitySet);
+ } else if (sc.ch == '/'
+ && (setOKBeforeRE.Contains(chPrevNonWhite)
+ || followsReturnKeyword(sc, styler))
+ && (!setCouldBePostOp.Contains(chPrevNonWhite)
+ || !FollowsPostfixOperator(sc, styler))) {
+ sc.SetState(SCE_C_REGEX|activitySet); // JavaScript's RegEx
} else if (sc.ch == '\"') {
- sc.SetState(SCE_C_STRING);
+ if (sc.chPrev == 'R') {
+ sc.SetState(SCE_C_STRINGRAW|activitySet);
+ rawStringTerminator = ")";
+ for (int termPos = sc.currentPos + 1;; termPos++) {
+ char chTerminator = styler.SafeGetCharAt(termPos, '(');
+ if (chTerminator == '(')
+ break;
+ rawStringTerminator += chTerminator;
+ }
+ rawStringTerminator += '\"';
+ } else {
+ sc.SetState(SCE_C_STRING|activitySet);
+ }
isIncludePreprocessor = false; // ensure that '>' won't end the string
} else if (isIncludePreprocessor && sc.ch == '<') {
- sc.SetState(SCE_C_STRING);
+ sc.SetState(SCE_C_STRING|activitySet);
} else if (sc.ch == '\'') {
- sc.SetState(SCE_C_CHARACTER);
+ sc.SetState(SCE_C_CHARACTER|activitySet);
} else if (sc.ch == '#' && visibleChars == 0) {
// Preprocessor commands are alone on their line
- sc.SetState(SCE_C_PREPROCESSOR);
+ sc.SetState(SCE_C_PREPROCESSOR|activitySet);
// Skip whitespace between # and preprocessor word
do {
sc.Forward();
} while ((sc.ch == ' ' || sc.ch == '\t') && sc.More());
if (sc.atLineEnd) {
- sc.SetState(SCE_C_DEFAULT);
+ sc.SetState(SCE_C_DEFAULT|activitySet);
} else if (sc.Match("include")) {
isIncludePreprocessor = true;
+ } else {
+ if (options.trackPreprocessor) {
+ if (sc.Match("ifdef") || sc.Match("ifndef")) {
+ bool isIfDef = sc.Match("ifdef");
+ int i = isIfDef ? 5 : 6;
+ std::string restOfLine = GetRestOfLine(styler, sc.currentPos + i + 1, false);
+ bool foundDef = preprocessorDefinitions.find(restOfLine) != preprocessorDefinitions.end();
+ preproc.StartSection(isIfDef == foundDef);
+ } else if (sc.Match("if")) {
+ std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true);
+ bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
+ preproc.StartSection(ifGood);
+ } else if (sc.Match("else")) {
+ if (!preproc.CurrentIfTaken()) {
+ preproc.InvertCurrentLevel();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ if (!activitySet)
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ } else if (!preproc.IsInactive()) {
+ preproc.InvertCurrentLevel();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ if (!activitySet)
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ }
+ } else if (sc.Match("elif")) {
+ // Ensure only one chosen out of #if .. #elif .. #elif .. #else .. #endif
+ if (!preproc.CurrentIfTaken()) {
+ // Similar to #if
+ std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 2, true);
+ bool ifGood = EvaluateExpression(restOfLine, preprocessorDefinitions);
+ if (ifGood) {
+ preproc.InvertCurrentLevel();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ if (!activitySet)
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ }
+ } else if (!preproc.IsInactive()) {
+ preproc.InvertCurrentLevel();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ if (!activitySet)
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ }
+ } else if (sc.Match("endif")) {
+ preproc.EndSection();
+ activitySet = preproc.IsInactive() ? activeFlag : 0;
+ sc.ChangeState(SCE_C_PREPROCESSOR|activitySet);
+ } else if (sc.Match("define")) {
+ if (options.updatePreprocessor && !preproc.IsInactive()) {
+ std::string restOfLine = GetRestOfLine(styler, sc.currentPos + 6, true);
+ if (restOfLine.find(")") == std::string::npos) { // Don't handle macros with arguments
+ std::vector<std::string> tokens = Tokenize(restOfLine);
+ std::string key;
+ std::string value("1");
+ if (tokens.size() >= 1) {
+ key = tokens[0];
+ if (tokens.size() >= 2) {
+ value = tokens[1];
+ }
+ preprocessorDefinitions[key] = value;
+ ppDefineHistory.push_back(PPDefinition(lineCurrent, key, value));
+ definitionsChanged = true;
+ }
+ }
+ }
+ }
+ }
}
} else if (isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_C_OPERATOR);
+ sc.SetState(SCE_C_OPERATOR|activitySet);
}
}
@@ -362,38 +909,22 @@ static void ColouriseCppDoc(unsigned int startPos, int length, int initStyle, Wo
}
continuationLine = false;
}
+ const bool rawStringsChanged = rawStringTerminators.Merge(rawSTNew, lineCurrent);
+ if (definitionsChanged || rawStringsChanged)
+ styler.ChangeLexerState(startPos, startPos + length);
sc.Complete();
}
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_C_COMMENT ||
- style == SCE_C_COMMENTDOC ||
- style == SCE_C_COMMENTDOCKEYWORD ||
- style == SCE_C_COMMENTDOCKEYWORDERROR;
-}
-
// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
-static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- // property fold.comment
- // This option enables folding multi-line comments and explicit fold points when using the C++ lexer.
- // Explicit fold points allows adding extra folding by placing a //{ comment at the start and a //}
- // at the end of a section that should fold.
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
+void SCI_METHOD LexerCPP::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
- // property fold.preprocessor
- // This option enables folding preprocessor directives when using the C++ lexer.
- // Includes C#'s explicit #region and #endregion folding directives.
- bool foldPreprocessor = styler.GetPropertyInt("fold.preprocessor") != 0;
+ if (!options.fold)
+ return;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-
- // property fold.at.else
- // This option enables C++ folding on a "} else {" line of an if statement.
- bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
+ LexAccessor styler(pAccess);
unsigned int endPos = startPos + length;
int visibleChars = 0;
@@ -404,16 +935,17 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
int levelMinCurrent = levelCurrent;
int levelNext = levelCurrent;
char chNext = styler[startPos];
- int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
+ int styleNext = MaskActive(styler.StyleAt(startPos));
+ int style = MaskActive(initStyle);
+ const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int stylePrev = style;
style = styleNext;
- styleNext = styler.StyleAt(i + 1);
+ styleNext = MaskActive(styler.StyleAt(i + 1));
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && IsStreamCommentStyle(style)) {
+ if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev) && (stylePrev != SCE_C_COMMENTLINEDOC)) {
levelNext++;
} else if (!IsStreamCommentStyle(styleNext) && (styleNext != SCE_C_COMMENTLINEDOC) && !atEOL) {
@@ -421,17 +953,25 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
levelNext--;
}
}
- if (foldComment && (style == SCE_C_COMMENTLINE)) {
- if ((ch == '/') && (chNext == '/')) {
- char chNext2 = styler.SafeGetCharAt(i + 2);
- if (chNext2 == '{') {
+ if (options.foldComment && options.foldCommentExplicit && ((style == SCE_C_COMMENTLINE) || options.foldExplicitAnywhere)) {
+ if (userDefinedFoldMarkers) {
+ if (styler.Match(i, options.foldExplicitStart.c_str())) {
levelNext++;
- } else if (chNext2 == '}') {
+ } else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
levelNext--;
}
+ } else {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}') {
+ levelNext--;
+ }
+ }
}
}
- if (foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
+ if (options.foldPreprocessor && (style == SCE_C_PREPROCESSOR)) {
if (ch == '#') {
unsigned int j = i + 1;
while ((j < endPos) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
@@ -444,7 +984,7 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
}
}
}
- if (style == SCE_C_OPERATOR) {
+ if (options.foldSyntaxBased && (style == SCE_C_OPERATOR)) {
if (ch == '{') {
// Measure the minimum before a '{' to allow
// folding on "} else {"
@@ -460,11 +1000,11 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
visibleChars++;
if (atEOL || (i == endPos-1)) {
int levelUse = levelCurrent;
- if (foldAtElse) {
+ if (options.foldSyntaxBased && options.foldAtElse) {
levelUse = levelMinCurrent;
}
int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
+ if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
@@ -483,24 +1023,154 @@ static void FoldCppDoc(unsigned int startPos, int length, int initStyle,
}
}
-static const char * const cppWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- "Documentation comment keywords",
- "Unused",
- "Global classes and typedefs",
- 0,
- };
+void LexerCPP::EvaluateTokens(std::vector<std::string> &tokens) {
-static void ColouriseCppDocSensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, true);
+ // Evaluate defined() statements to either 0 or 1
+ for (size_t i=0; (i+2)<tokens.size();) {
+ if ((tokens[i] == "defined") && (tokens[i+1] == "(")) {
+ const char *val = "0";
+ if (tokens[i+2] == ")") {
+ // defined()
+ tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 3);
+ } else if (((i+2)<tokens.size()) && (tokens[i+3] == ")")) {
+ // defined(<int>)
+ tokens.erase(tokens.begin() + i + 1, tokens.begin() + i + 4);
+ val = "1";
+ }
+ tokens[i] = val;
+ } else {
+ i++;
+ }
+ }
+
+ // Find bracketed subexpressions and recurse on them
+ std::vector<std::string>::iterator itBracket = std::find(tokens.begin(), tokens.end(), "(");
+ std::vector<std::string>::iterator itEndBracket = std::find(tokens.begin(), tokens.end(), ")");
+ while ((itBracket != tokens.end()) && (itEndBracket != tokens.end()) && (itEndBracket > itBracket)) {
+ std::vector<std::string> inBracket(itBracket + 1, itEndBracket);
+ EvaluateTokens(inBracket);
+
+ // The insertion is done before the removal because there were failures with the opposite approach
+ tokens.insert(itBracket, inBracket.begin(), inBracket.end());
+ itBracket = std::find(tokens.begin(), tokens.end(), "(");
+ itEndBracket = std::find(tokens.begin(), tokens.end(), ")");
+ tokens.erase(itBracket, itEndBracket + 1);
+
+ itBracket = std::find(tokens.begin(), tokens.end(), "(");
+ itEndBracket = std::find(tokens.begin(), tokens.end(), ")");
+ }
+
+ // Evaluate logical negations
+ for (size_t j=0; (j+1)<tokens.size();) {
+ if (setNegationOp.Contains(tokens[j][0])) {
+ int isTrue = atoi(tokens[j+1].c_str());
+ if (tokens[j] == "!")
+ isTrue = !isTrue;
+ std::vector<std::string>::iterator itInsert =
+ tokens.erase(tokens.begin() + j, tokens.begin() + j + 2);
+ tokens.insert(itInsert, isTrue ? "1" : "0");
+ } else {
+ j++;
+ }
+ }
+
+ // Evaluate expressions in precedence order
+ enum precedence { precArithmetic, precRelative, precLogical };
+ for (int prec=precArithmetic; prec <= precLogical; prec++) {
+ // Looking at 3 tokens at a time so end at 2 before end
+ for (size_t k=0; (k+2)<tokens.size();) {
+ char chOp = tokens[k+1][0];
+ if (
+ ((prec==precArithmetic) && setArithmethicOp.Contains(chOp)) ||
+ ((prec==precRelative) && setRelOp.Contains(chOp)) ||
+ ((prec==precLogical) && setLogicalOp.Contains(chOp))
+ ) {
+ int valA = atoi(tokens[k].c_str());
+ int valB = atoi(tokens[k+2].c_str());
+ int result = 0;
+ if (tokens[k+1] == "+")
+ result = valA + valB;
+ else if (tokens[k+1] == "-")
+ result = valA - valB;
+ else if (tokens[k+1] == "*")
+ result = valA * valB;
+ else if (tokens[k+1] == "/")
+ result = valA / (valB ? valB : 1);
+ else if (tokens[k+1] == "%")
+ result = valA % (valB ? valB : 1);
+ else if (tokens[k+1] == "<")
+ result = valA < valB;
+ else if (tokens[k+1] == "<=")
+ result = valA <= valB;
+ else if (tokens[k+1] == ">")
+ result = valA > valB;
+ else if (tokens[k+1] == ">=")
+ result = valA >= valB;
+ else if (tokens[k+1] == "==")
+ result = valA == valB;
+ else if (tokens[k+1] == "!=")
+ result = valA != valB;
+ else if (tokens[k+1] == "||")
+ result = valA || valB;
+ else if (tokens[k+1] == "&&")
+ result = valA && valB;
+ char sResult[30];
+ sprintf(sResult, "%d", result);
+ std::vector<std::string>::iterator itInsert =
+ tokens.erase(tokens.begin() + k, tokens.begin() + k + 3);
+ tokens.insert(itInsert, sResult);
+ } else {
+ k++;
+ }
+ }
+ }
}
-static void ColouriseCppDocInsensitive(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- ColouriseCppDoc(startPos, length, initStyle, keywordlists, styler, false);
+bool LexerCPP::EvaluateExpression(const std::string &expr, const std::map<std::string, std::string> &preprocessorDefinitions) {
+ // Break into tokens, replacing with definitions
+ std::string word;
+ std::vector<std::string> tokens;
+ const char *cp = expr.c_str();
+ for (;;) {
+ if (setWord.Contains(*cp)) {
+ word += *cp;
+ } else {
+ std::map<std::string, std::string>::const_iterator it = preprocessorDefinitions.find(word);
+ if (it != preprocessorDefinitions.end()) {
+ tokens.push_back(it->second);
+ } else if (!word.empty() && ((word[0] >= '0' && word[0] <= '9') || (word == "defined"))) {
+ tokens.push_back(word);
+ }
+ word = "";
+ if (!*cp) {
+ break;
+ }
+ if ((*cp != ' ') && (*cp != '\t')) {
+ std::string op(cp, 1);
+ if (setRelOp.Contains(*cp)) {
+ if (setRelOp.Contains(cp[1])) {
+ op += cp[1];
+ cp++;
+ }
+ } else if (setLogicalOp.Contains(*cp)) {
+ if (setLogicalOp.Contains(cp[1])) {
+ op += cp[1];
+ cp++;
+ }
+ }
+ tokens.push_back(op);
+ }
+ }
+ cp++;
+ }
+
+ EvaluateTokens(tokens);
+
+ // "0" or "" -> false else true
+ bool isFalse = tokens.empty() ||
+ ((tokens.size() == 1) && ((tokens[0] == "") || tokens[0] == "0"));
+ return !isFalse;
}
-LexerModule lmCPP(SCLEX_CPP, ColouriseCppDocSensitive, "cpp", FoldCppDoc, cppWordLists);
-LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, ColouriseCppDocInsensitive, "cppnocase", FoldCppDoc, cppWordLists);
+LexerModule lmCPP(SCLEX_CPP, LexerCPP::LexerFactoryCPP, "cpp", cppWordLists);
+LexerModule lmCPPNoCase(SCLEX_CPPNOCASE, LexerCPP::LexerFactoryCPPInsensitive, "cppnocase", cppWordLists);
diff --git a/plugins/scintilla/scintilla/LexCSS.cxx b/plugins/scintilla/scintilla/LexCSS.cxx
index 3b139cd..8fbca38 100644
--- a/plugins/scintilla/scintilla/LexCSS.cxx
+++ b/plugins/scintilla/scintilla/LexCSS.cxx
@@ -9,18 +9,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -62,6 +65,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
int lastState = -1; // before operator
int lastStateC = -1; // before comment
+ int lastStateS = -1; // before single-quoted/double-quoted string
int op = ' '; // last operator
int opPrev = ' '; // last operator
@@ -105,7 +109,7 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
i--;
if ((sc.currentPos - i) % 2 == 1)
continue;
- sc.ForwardSetState(SCE_CSS_VALUE);
+ sc.ForwardSetState(lastStateS);
}
if (sc.state == SCE_CSS_OPERATOR) {
@@ -140,9 +144,9 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
sc.SetState(SCE_CSS_TAG);
break;
case '{':
- if (lastState == SCE_CSS_DIRECTIVE)
+ if (lastState == SCE_CSS_MEDIA)
sc.SetState(SCE_CSS_DEFAULT);
- else if (lastState == SCE_CSS_TAG)
+ else if (lastState == SCE_CSS_TAG || lastState == SCE_CSS_DIRECTIVE)
sc.SetState(SCE_CSS_IDENTIFIER);
break;
case '}':
@@ -219,7 +223,8 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
sc.state == SCE_CSS_PSEUDOCLASS || sc.state == SCE_CSS_PSEUDOELEMENT ||
sc.state == SCE_CSS_EXTENDED_PSEUDOCLASS || sc.state == SCE_CSS_EXTENDED_PSEUDOELEMENT ||
sc.state == SCE_CSS_UNKNOWN_PSEUDOCLASS ||
- sc.state == SCE_CSS_IMPORTANT
+ sc.state == SCE_CSS_IMPORTANT ||
+ sc.state == SCE_CSS_DIRECTIVE
)) {
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
@@ -263,6 +268,10 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
if (strcmp(s2, "important") != 0)
sc.ChangeState(SCE_CSS_VALUE);
break;
+ case SCE_CSS_DIRECTIVE:
+ if (op == '@' && strcmp(s2, "media") == 0)
+ sc.ChangeState(SCE_CSS_MEDIA);
+ break;
}
}
@@ -280,12 +289,14 @@ static void ColouriseCssDoc(unsigned int startPos, int length, int initStyle, Wo
lastStateC = sc.state;
sc.SetState(SCE_CSS_COMMENT);
sc.Forward();
- } else if (sc.state == SCE_CSS_VALUE && (sc.ch == '\"' || sc.ch == '\'')) {
+ } else if ((sc.state == SCE_CSS_VALUE || sc.state == SCE_CSS_ATTRIBUTE)
+ && (sc.ch == '\"' || sc.ch == '\'')) {
+ lastStateS = sc.state;
sc.SetState((sc.ch == '\"' ? SCE_CSS_DOUBLESTRING : SCE_CSS_SINGLESTRING));
} else if (IsCssOperator(sc.ch)
&& (sc.state != SCE_CSS_ATTRIBUTE || sc.ch == ']')
&& (sc.state != SCE_CSS_VALUE || sc.ch == ';' || sc.ch == '}' || sc.ch == '!')
- && (sc.state != SCE_CSS_DIRECTIVE || sc.ch == ';' || sc.ch == '{')
+ && ((sc.state != SCE_CSS_DIRECTIVE && sc.state != SCE_CSS_MEDIA) || sc.ch == ';' || sc.ch == '{')
) {
if (sc.state != SCE_CSS_OPERATOR)
lastState = sc.state;
diff --git a/plugins/scintilla/scintilla/LexCaml.cxx b/plugins/scintilla/scintilla/LexCaml.cxx
index 0d11622..f576e3e 100644
--- a/plugins/scintilla/scintilla/LexCaml.cxx
+++ b/plugins/scintilla/scintilla/LexCaml.cxx
@@ -20,19 +20,22 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
// Since the Microsoft __iscsym[f] funcs are not ANSI...
inline int iscaml(int c) {return isalnum(c) || c == '_';}
@@ -51,9 +54,13 @@ using namespace Scintilla;
/*
(actually seems to work!)
*/
+#include <string>
#include "WindowAccessor.h"
#include "ExternalLexer.h"
+#undef EXT_LEXER_DECL
+#define EXT_LEXER_DECL __declspec( dllexport ) __stdcall
+
#if PLAT_WIN
#include <windows.h>
#endif
@@ -430,13 +437,11 @@ void ColouriseCamlDoc(
static
#endif /* BUILD_AS_EXTERNAL_LEXER */
void FoldCamlDoc(
- unsigned int startPos, int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler)
+ unsigned int, int,
+ int,
+ WordList *[],
+ Accessor &)
{
- // below useless evaluation(s) to supress "not used" warnings
- startPos || length || initStyle || keywordlists[0] || styler.Length();
}
static const char * const camlWordListDesc[] = {
diff --git a/plugins/scintilla/scintilla/LexCmake.cxx b/plugins/scintilla/scintilla/LexCmake.cxx
index 1f51f47..70e9dee 100644
--- a/plugins/scintilla/scintilla/LexCmake.cxx
+++ b/plugins/scintilla/scintilla/LexCmake.cxx
@@ -5,21 +5,25 @@
// Copyright 2007 by Cristian Adam <cristian [dot] adam [at] gmx [dot] net>
// based on the NSIS lexer
// The License.txt file describes the conditions under which this software may be distributed.
+
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "CharClassify.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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
diff --git a/plugins/scintilla/scintilla/LexConf.cxx b/plugins/scintilla/scintilla/LexConf.cxx
index 969275f..5e1bd19 100644
--- a/plugins/scintilla/scintilla/LexConf.cxx
+++ b/plugins/scintilla/scintilla/LexConf.cxx
@@ -11,18 +11,22 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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
@@ -70,17 +74,17 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
} else if( ch == '"') {
state = SCE_CONF_STRING;
styler.ColourTo(i,SCE_CONF_STRING);
- } else if( ispunct(ch) ) {
+ } else if( isascii(ch) && ispunct(ch) ) {
// signals an operator...
// no state jump necessary for this
// simple case...
styler.ColourTo(i,SCE_CONF_OPERATOR);
- } else if( isalpha(ch) ) {
+ } else if( isascii(ch) && isalpha(ch) ) {
// signals the start of an identifier
bufferCount = 0;
buffer[bufferCount++] = static_cast<char>(tolower(ch));
state = SCE_CONF_IDENTIFIER;
- } else if( isdigit(ch) ) {
+ } else if( isascii(ch) && isdigit(ch) ) {
// signals the start of a number
bufferCount = 0;
buffer[bufferCount++] = ch;
@@ -107,7 +111,7 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
// if we find a non-alphanumeric char,
// we simply go to default state
// else we're still dealing with an extension...
- if( isalnum(ch) || (ch == '_') ||
+ if( (isascii(ch) && isalnum(ch)) || (ch == '_') ||
(ch == '-') || (ch == '$') ||
(ch == '/') || (ch == '.') || (ch == '*') )
{
@@ -129,7 +133,7 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
case SCE_CONF_IDENTIFIER:
// stay in CONF_IDENTIFIER state until we find a non-alphanumeric
- if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
+ if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') || (ch == '$') || (ch == '.') || (ch == '*')) {
buffer[bufferCount++] = static_cast<char>(tolower(ch));
} else {
state = SCE_CONF_DEFAULT;
@@ -154,7 +158,7 @@ static void ColouriseConfDoc(unsigned int startPos, int length, int, WordList *k
case SCE_CONF_NUMBER:
// stay in CONF_NUMBER state until we find a non-numeric
- if( isdigit(ch) || ch == '.') {
+ if( (isascii(ch) && isdigit(ch)) || ch == '.') {
buffer[bufferCount++] = ch;
} else {
state = SCE_CONF_DEFAULT;
diff --git a/plugins/scintilla/scintilla/LexCrontab.cxx b/plugins/scintilla/scintilla/LexCrontab.cxx
old mode 100755
new mode 100644
index 62044c3..08abc71
--- a/plugins/scintilla/scintilla/LexCrontab.cxx
+++ b/plugins/scintilla/scintilla/LexCrontab.cxx
@@ -9,18 +9,22 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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
@@ -94,12 +98,12 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
// signals an asterisk
// no state jump necessary for this simple case...
styler.ColourTo(i,SCE_NNCRONTAB_ASTERISK);
- } else if( isalpha(ch) || ch == '<' ) {
+ } else if( (isascii(ch) && isalpha(ch)) || ch == '<' ) {
// signals the start of an identifier
bufferCount = 0;
buffer[bufferCount++] = ch;
state = SCE_NNCRONTAB_IDENTIFIER;
- } else if( isdigit(ch) ) {
+ } else if( isascii(ch) && isdigit(ch) ) {
// signals the start of a number
bufferCount = 0;
buffer[bufferCount++] = ch;
@@ -167,7 +171,7 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
case SCE_NNCRONTAB_IDENTIFIER:
// stay in CONF_IDENTIFIER state until we find a non-alphanumeric
- if( isalnum(ch) || (ch == '_') || (ch == '-') || (ch == '/') ||
+ if( (isascii(ch) && isalnum(ch)) || (ch == '_') || (ch == '-') || (ch == '/') ||
(ch == '$') || (ch == '.') || (ch == '<') || (ch == '>') ||
(ch == '@') ) {
buffer[bufferCount++] = ch;
@@ -196,7 +200,7 @@ static void ColouriseNncrontabDoc(unsigned int startPos, int length, int, WordLi
case SCE_NNCRONTAB_NUMBER:
// stay in CONF_NUMBER state until we find a non-numeric
- if( isdigit(ch) /* || ch == '.' */ ) {
+ if( isascii(ch) && isdigit(ch) /* || ch == '.' */ ) {
buffer[bufferCount++] = ch;
} else {
state = SCE_NNCRONTAB_DEFAULT;
diff --git a/plugins/scintilla/scintilla/LexCsound.cxx b/plugins/scintilla/scintilla/LexCsound.cxx
index 4162c9b..8e5880c 100644
--- a/plugins/scintilla/scintilla/LexCsound.cxx
+++ b/plugins/scintilla/scintilla/LexCsound.cxx
@@ -8,18 +8,22 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
-#include "Platform.h"
+#include <assert.h>
+#include <ctype.h>
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.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
@@ -35,7 +39,7 @@ static inline bool IsAWordStart(const int ch) {
}
static inline bool IsCsoundOperator(char ch) {
- if (isalnum(ch))
+ if (isascii(ch) && isalnum(ch))
return false;
// '.' left out as it is used to make up numbers
if (ch == '*' || ch == '/' || ch == '-' || ch == '+' ||
@@ -72,7 +76,7 @@ static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle,
continue;
}
}
-
+
// Determine if the current state should terminate.
if (sc.state == SCE_CSOUND_OPERATOR) {
if (!IsCsoundOperator(static_cast<char>(sc.ch))) {
@@ -119,7 +123,7 @@ static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_CSOUND_DEFAULT);
}
}
-
+
// Determine if a new state should be entered.
if (sc.state == SCE_CSOUND_DEFAULT) {
if (sc.ch == ';'){
@@ -146,7 +150,7 @@ static void ColouriseCsoundDoc(unsigned int startPos, int length, int initStyle,
sc.Complete();
}
-static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[],
+static void FoldCsoundInstruments(unsigned int startPos, int length, int /* initStyle */, WordList *[],
Accessor &styler) {
unsigned int lengthDoc = startPos + length;
int visibleChars = 0;
diff --git a/plugins/scintilla/scintilla/LexD.cxx b/plugins/scintilla/scintilla/LexD.cxx
index 4c4bcb3..5b8f9e7 100644
--- a/plugins/scintilla/scintilla/LexD.cxx
+++ b/plugins/scintilla/scintilla/LexD.cxx
@@ -2,25 +2,36 @@
** Lexer for D.
**
** Copyright (c) 2006 by Waldemar Augustyn <waldemar wdmsys com>
+ ** Converted to lexer object and added further folding features/properties by "Udo Lechner" <dlchnr(at)gmx(dot)net>
**/
// Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
-#include "Platform.h"
+#include <string>
+#include <map>
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
+
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
@@ -55,17 +66,187 @@ static bool IsStringSuffix(int ch) {
return ch == 'c' || ch == 'w' || ch == 'd';
}
+static bool IsStreamCommentStyle(int style) {
+ return style == SCE_D_COMMENT ||
+ style == SCE_D_COMMENTDOC ||
+ style == SCE_D_COMMENTDOCKEYWORD ||
+ style == SCE_D_COMMENTDOCKEYWORDERROR;
+}
-static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler, bool caseSensitive) {
+// An individual named option for use in an OptionSet
- WordList &keywords = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &keywords3 = *keywordlists[2]; //doxygen
- WordList &keywords4 = *keywordlists[3];
- WordList &keywords5 = *keywordlists[4];
- WordList &keywords6 = *keywordlists[5];
- WordList &keywords7 = *keywordlists[6];
+// Options used for LexerD
+struct OptionsD {
+ bool fold;
+ bool foldSyntaxBased;
+ bool foldComment;
+ bool foldCommentMultiline;
+ bool foldCommentExplicit;
+ std::string foldExplicitStart;
+ std::string foldExplicitEnd;
+ bool foldExplicitAnywhere;
+ bool foldCompact;
+ int foldAtElseInt;
+ bool foldAtElse;
+ OptionsD() {
+ fold = false;
+ foldSyntaxBased = true;
+ foldComment = false;
+ foldCommentMultiline = true;
+ foldCommentExplicit = true;
+ foldExplicitStart = "";
+ foldExplicitEnd = "";
+ foldExplicitAnywhere = false;
+ foldCompact = true;
+ foldAtElseInt = -1;
+ foldAtElse = false;
+ }
+};
+
+static const char * const dWordLists[] = {
+ "Primary keywords and identifiers",
+ "Secondary keywords and identifiers",
+ "Documentation comment keywords",
+ "Type definitions and aliases",
+ "Keywords 5",
+ "Keywords 6",
+ "Keywords 7",
+ 0,
+ };
+
+struct OptionSetD : public OptionSet<OptionsD> {
+ OptionSetD() {
+ DefineProperty("fold", &OptionsD::fold);
+
+ DefineProperty("fold.d.syntax.based", &OptionsD::foldSyntaxBased,
+ "Set this property to 0 to disable syntax based folding.");
+
+ DefineProperty("fold.comment", &OptionsD::foldComment);
+
+ DefineProperty("fold.d.comment.multiline", &OptionsD::foldCommentMultiline,
+ "Set this property to 0 to disable folding multi-line comments when fold.comment=1.");
+
+ DefineProperty("fold.d.comment.explicit", &OptionsD::foldCommentExplicit,
+ "Set this property to 0 to disable folding explicit fold points when fold.comment=1.");
+
+ DefineProperty("fold.d.explicit.start", &OptionsD::foldExplicitStart,
+ "The string to use for explicit fold start points, replacing the standard //{.");
+
+ DefineProperty("fold.d.explicit.end", &OptionsD::foldExplicitEnd,
+ "The string to use for explicit fold end points, replacing the standard //}.");
+
+ DefineProperty("fold.d.explicit.anywhere", &OptionsD::foldExplicitAnywhere,
+ "Set this property to 1 to enable explicit fold points anywhere, not just in line comments.");
+
+ DefineProperty("fold.compact", &OptionsD::foldCompact);
+
+ DefineProperty("lexer.d.fold.at.else", &OptionsD::foldAtElseInt,
+ "This option enables D folding on a \"} else {\" line of an if statement.");
+
+ DefineProperty("fold.at.else", &OptionsD::foldAtElse);
+
+ DefineWordListSets(dWordLists);
+ }
+};
+
+class LexerD : public ILexer {
+ bool caseSensitive;
+ WordList keywords;
+ WordList keywords2;
+ WordList keywords3;
+ WordList keywords4;
+ WordList keywords5;
+ WordList keywords6;
+ WordList keywords7;
+ OptionsD options;
+ OptionSetD osD;
+public:
+ LexerD(bool caseSensitive_) :
+ caseSensitive(caseSensitive_) {
+ }
+ ~LexerD() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char * SCI_METHOD PropertyNames() {
+ return osD.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osD.PropertyType(name);
+ }
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osD.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osD.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ 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);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactoryD() {
+ return new LexerD(true);
+ }
+ static ILexer *LexerFactoryDInsensitive() {
+ return new LexerD(false);
+ }
+};
+
+int SCI_METHOD LexerD::PropertySet(const char *key, const char *val) {
+ if (osD.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerD::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywords;
+ break;
+ case 1:
+ wordListN = &keywords2;
+ break;
+ case 2:
+ wordListN = &keywords3;
+ break;
+ case 3:
+ wordListN = &keywords4;
+ break;
+ case 4:
+ wordListN = &keywords5;
+ break;
+ case 5:
+ wordListN = &keywords6;
+ break;
+ case 6:
+ wordListN = &keywords7;
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerD::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
int styleBeforeDCKeyword = SCE_D_DEFAULT;
@@ -290,24 +471,17 @@ static void ColouriseDoc(unsigned int startPos, int length, int initStyle,
sc.Complete();
}
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_D_COMMENT ||
- style == SCE_D_COMMENTDOC ||
- style == SCE_D_COMMENTDOCKEYWORD ||
- style == SCE_D_COMMENTDOCKEYWORDERROR;
-}
-
// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
-static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
-
- // property lexer.d.fold.at.else
- // This option enables D folding on a "} else {" line of an if statement.
- bool foldAtElse = styler.GetPropertyInt("lexer.d.fold.at.else",
- styler.GetPropertyInt("fold.at.else", 0)) != 0;
+
+void SCI_METHOD LexerD::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+
+ if (!options.fold)
+ return;
+
+ LexAccessor styler(pAccess);
+
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
@@ -319,6 +493,8 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
+ bool foldAtElse = options.foldAtElseInt >= 0 ? options.foldAtElseInt != 0 : options.foldAtElse;
+ const bool userDefinedFoldMarkers = !options.foldExplicitStart.empty() && !options.foldExplicitEnd.empty();
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
@@ -326,7 +502,7 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && IsStreamCommentStyle(style)) {
+ if (options.foldComment && options.foldCommentMultiline && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
levelNext++;
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
@@ -334,7 +510,25 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
levelNext--;
}
}
- if (style == SCE_D_OPERATOR) {
+ if (options.foldComment && options.foldCommentExplicit && ((style == SCE_D_COMMENTLINE) || options.foldExplicitAnywhere)) {
+ if (userDefinedFoldMarkers) {
+ if (styler.Match(i, options.foldExplicitStart.c_str())) {
+ levelNext++;
+ } else if (styler.Match(i, options.foldExplicitEnd.c_str())) {
+ levelNext--;
+ }
+ } else {
+ if ((ch == '/') && (chNext == '/')) {
+ char chNext2 = styler.SafeGetCharAt(i + 2);
+ if (chNext2 == '{') {
+ levelNext++;
+ } else if (chNext2 == '}') {
+ levelNext--;
+ }
+ }
+ }
+ }
+ if (options.foldSyntaxBased && (style == SCE_D_OPERATOR)) {
if (ch == '{') {
// Measure the minimum before a '{' to allow
// folding on "} else {"
@@ -346,19 +540,19 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
levelNext--;
}
}
- if (atEOL) {
- if (foldComment) { // Handle nested comments
+ if (atEOL || (i == endPos-1)) {
+ if (options.foldComment && options.foldCommentMultiline) { // Handle nested comments
int nc;
nc = styler.GetLineState(lineCurrent);
nc -= lineCurrent>0? styler.GetLineState(lineCurrent-1): 0;
levelNext += nc;
}
int levelUse = levelCurrent;
- if (foldAtElse) {
+ if (options.foldSyntaxBased && foldAtElse) {
levelUse = levelMinCurrent;
}
int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
+ if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
@@ -375,25 +569,4 @@ static void FoldDoc(unsigned int startPos, int length, int initStyle, Accessor &
}
}
-static void FoldDDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- FoldDoc(startPos, length, initStyle, styler);
-}
-
-static const char * const dWordLists[] = {
- "Primary keywords and identifiers",
- "Secondary keywords and identifiers",
- "Documentation comment keywords",
- "Type definitions and aliases",
- "Keywords 5",
- "Keywords 6",
- "Keywords 7",
- 0,
- };
-
-static void ColouriseDDoc(unsigned int startPos, int length,
- int initStyle, WordList *keywordlists[], Accessor &styler) {
- ColouriseDoc(startPos, length, initStyle, keywordlists, styler, true);
-}
-
-LexerModule lmD(SCLEX_D, ColouriseDDoc, "d", FoldDDoc, dWordLists);
+LexerModule lmD(SCLEX_D, LexerD::LexerFactoryD, "d", dWordLists);
diff --git a/plugins/scintilla/scintilla/LexEScript.cxx b/plugins/scintilla/scintilla/LexEScript.cxx
index 295aaec..9a7560e 100644
--- a/plugins/scintilla/scintilla/LexEScript.cxx
+++ b/plugins/scintilla/scintilla/LexEScript.cxx
@@ -9,15 +9,18 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -198,7 +201,7 @@ static void FoldESCRIPTDoc(unsigned int startPos, int length, int initStyle, Wor
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
-
+
if (foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
levelCurrent++;
diff --git a/plugins/scintilla/scintilla/LexEiffel.cxx b/plugins/scintilla/scintilla/LexEiffel.cxx
old mode 100755
new mode 100644
index 03dea5e..067801c
--- a/plugins/scintilla/scintilla/LexEiffel.cxx
+++ b/plugins/scintilla/scintilla/LexEiffel.cxx
@@ -7,18 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexErlang.cxx b/plugins/scintilla/scintilla/LexErlang.cxx
index 45577bd..5f52258 100644
--- a/plugins/scintilla/scintilla/LexErlang.cxx
+++ b/plugins/scintilla/scintilla/LexErlang.cxx
@@ -4,24 +4,28 @@
/** @file LexErlang.cxx
** Lexer for Erlang.
** Enhanced by Etienne 'Lenain' Girondel (lenaing gmail com)
- ** Originally wrote by Peter-Henry Mander,
+ ** Originally wrote by Peter-Henry Mander,
** based on Matlab lexer by José Fonseca.
**/
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.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
@@ -152,7 +156,7 @@ static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
// Try to match documentation comment
sc.GetCurrent(cur, sizeof(cur));
- if (parse_state == COMMENT_DOC_MACRO
+ if (parse_state == COMMENT_DOC_MACRO
&& erlangDocMacro.InList(cur)) {
sc.ChangeState(SCE_ERLANG_COMMENT_DOC_MACRO);
while (sc.ch != '}' && !sc.atLineEnd)
@@ -340,7 +344,7 @@ static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
case NUMERAL_BASE_VALUE : {
if (!is_radix(radix_digits,sc.ch)) {
radix_digits = 0;
-
+
if (!isalnum(sc.ch))
sc.ChangeState(SCE_ERLANG_NUMBER);
@@ -380,7 +384,7 @@ static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
/* Preprocessor --------------------------------------------------*/
case PREPROCESSOR : {
if (!IsAWordChar(sc.ch)) {
-
+
sc.GetCurrent(cur, sizeof(cur));
if (erlangPreproc.InList(cur)) {
style = SCE_ERLANG_PREPROC;
@@ -421,7 +425,7 @@ static void ColouriseErlangDoc(unsigned int startPos, int length, int initStyle,
} break;
case SCE_ERLANG_OPERATOR : {
if (sc.chPrev == '.') {
- if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\'
+ if (sc.ch == '*' || sc.ch == '/' || sc.ch == '\\'
|| sc.ch == '^') {
sc.ForwardSetState(SCE_ERLANG_DEFAULT);
} else if (sc.ch == '\'') {
diff --git a/plugins/scintilla/scintilla/LexFlagship.cxx b/plugins/scintilla/scintilla/LexFlagship.cxx
index baf2941..b8568b0 100644
--- a/plugins/scintilla/scintilla/LexFlagship.cxx
+++ b/plugins/scintilla/scintilla/LexFlagship.cxx
@@ -1,169 +1,299 @@
// Scintilla source code edit control
/** @file LexFlagShip.cxx
- ** Lexer for FlagShip
- ** (Syntactically compatible to other XBase dialects, like dBase, Clipper, Fox etc.)
+ ** Lexer for Harbour and FlagShip.
+ ** (Syntactically compatible to other xBase dialects, like Clipper, dBase, Clip, FoxPro etc.)
**/
// Copyright 2005 by Randy Butler
+// Copyright 2010 by Xavi <jarabal/at/gmail.com> (Harbour)
// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
-static bool IsFlagShipComment(Accessor &styler, int pos, int len) {
- return len>0 && styler[pos]=='\'';
-}
-
-static inline bool IsTypeCharacter(int ch) {
- return ch == '%' || ch == '&' || ch == '@' || ch == '!' || ch == '#' || ch == '$';
-}
-
// Extended to accept accented characters
-static inline bool IsAWordChar(int ch) {
+static inline bool IsAWordChar(int ch)
+{
return ch >= 0x80 ||
- (isalnum(ch) || ch == '.' || ch == '_');
-}
-
-static inline bool IsAWordStart(int ch) {
- return ch >= 0x80 ||
- (isalnum(ch) || ch == '_');
-}
-
-static inline bool IsADateCharacter(const int ch) {
- return (ch < 0x80) &&
- (isalnum(ch) || ch == '|' || ch == '-' || ch == '/' || ch == ':' || ch == ' ' || ch == '\t');
+ (isalnum(ch) || ch == '_');
}
-
static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
+ WordList *keywordlists[], Accessor &styler)
+{
- //bool FSScriptSyntax = true;
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
+
+ // property lexer.flagship.styling.within.preprocessor
+ // For Harbour code, determines whether all preprocessor code is styled in the preprocessor style (0) or only from the
+ // initial # to the end of the command word(1, the default). It also determines how to present text, dump, and disabled code.
+ bool stylingWithinPreprocessor = styler.GetPropertyInt("lexer.flagship.styling.within.preprocessor", 1) != 0;
- styler.StartAt(startPos);
+ CharacterSet setDoxygen(CharacterSet::setAlpha, "$ \\&<>#{}[]");
int visibleChars = 0;
+ int closeStringChar = 0;
+ int styleBeforeDCKeyword = SCE_FS_DEFAULT;
+ bool bEnableCode = initStyle < SCE_FS_DISABLEDCODE;
StyleContext sc(startPos, length, initStyle, styler);
for (; sc.More(); sc.Forward()) {
- if (sc.state == SCE_FS_OPERATOR) {
- sc.SetState(SCE_FS_DEFAULT);
- } else if (sc.state == SCE_FS_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
- char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
- if (keywords.InList(s)) {
- sc.ChangeState(SCE_FS_KEYWORD);
- } else if (keywords2.InList(s)) {
- sc.ChangeState(SCE_FS_KEYWORD2);
- } else if (keywords3.InList(s)) {
- sc.ChangeState(SCE_FS_KEYWORD3);
- } else if (keywords4.InList(s)) {
- sc.ChangeState(SCE_FS_KEYWORD4);
- }// Else, it is really an identifier...
- sc.SetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_NUMBER) {
- if (!IsAWordChar(sc.ch)) {
- sc.SetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_STRING) {
- // VB doubles quotes to preserve them, so just end this string
- // state now as a following quote will start again
- if (sc.ch == '\"') {
- if (tolower(sc.chNext) == 'c') {
+ // Determine if the current state should terminate.
+ switch (sc.state) {
+ case SCE_FS_OPERATOR:
+ case SCE_FS_OPERATOR_C:
+ case SCE_FS_WORDOPERATOR:
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ break;
+ case SCE_FS_IDENTIFIER:
+ case SCE_FS_IDENTIFIER_C:
+ if (!IsAWordChar(sc.ch)) {
+ char s[64];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (keywords.InList(s)) {
+ sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD : SCE_FS_KEYWORD_C);
+ } else if (keywords2.InList(s)) {
+ sc.ChangeState(bEnableCode ? SCE_FS_KEYWORD2 : SCE_FS_KEYWORD2_C);
+ } else if (bEnableCode && keywords3.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD3);
+ } else if (bEnableCode && keywords4.InList(s)) {
+ sc.ChangeState(SCE_FS_KEYWORD4);
+ }// Else, it is really an identifier...
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ break;
+ case SCE_FS_NUMBER:
+ if (!IsAWordChar(sc.ch) && !(sc.ch == '.' && IsADigit(sc.chNext))) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ break;
+ case SCE_FS_NUMBER_C:
+ if (!IsAWordChar(sc.ch) && sc.ch != '.') {
+ sc.SetState(SCE_FS_DEFAULT_C);
+ }
+ break;
+ case SCE_FS_CONSTANT:
+ if (!IsAWordChar(sc.ch)) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ break;
+ case SCE_FS_STRING:
+ case SCE_FS_STRING_C:
+ if (sc.ch == closeStringChar) {
+ sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(bEnableCode ? SCE_FS_STRINGEOL : SCE_FS_STRINGEOL_C);
+ }
+ break;
+ case SCE_FS_STRINGEOL:
+ case SCE_FS_STRINGEOL_C:
+ if (sc.atLineStart) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ break;
+ case SCE_FS_COMMENTDOC:
+ case SCE_FS_COMMENTDOC_C:
+ if (sc.Match('*', '/')) {
sc.Forward();
+ sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '*') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C;
+ sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_FS_COMMENT:
+ case SCE_FS_COMMENTLINE:
+ if (sc.atLineStart) {
+ sc.SetState(SCE_FS_DEFAULT);
+ }
+ break;
+ case SCE_FS_COMMENTLINEDOC:
+ case SCE_FS_COMMENTLINEDOC_C:
+ if (sc.atLineStart) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (sc.ch == '@' || sc.ch == '\\') { // JavaDoc and Doxygen support
+ // Verify that we have the conditions to mark a comment-doc-keyword
+ if ((IsASpace(sc.chPrev) || sc.chPrev == '/' || sc.chPrev == '!') && (!IsASpace(sc.chNext))) {
+ styleBeforeDCKeyword = bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C;
+ sc.SetState(SCE_FS_COMMENTDOCKEYWORD);
+ }
+ }
+ break;
+ case SCE_FS_COMMENTDOCKEYWORD:
+ if ((styleBeforeDCKeyword == SCE_FS_COMMENTDOC || styleBeforeDCKeyword == SCE_FS_COMMENTDOC_C) &&
+ sc.Match('*', '/')) {
+ sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
+ sc.Forward();
+ sc.ForwardSetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (!setDoxygen.Contains(sc.ch)) {
+ char s[64];
+ sc.GetCurrentLowered(s, sizeof(s));
+ if (!IsASpace(sc.ch) || !keywords5.InList(s + 1)) {
+ sc.ChangeState(SCE_FS_COMMENTDOCKEYWORDERROR);
+ }
+ sc.SetState(styleBeforeDCKeyword);
+ }
+ break;
+ case SCE_FS_PREPROCESSOR:
+ case SCE_FS_PREPROCESSOR_C:
+ if (sc.atLineEnd) {
+ if (!(sc.chPrev == ';' || sc.GetRelative(-2) == ';')) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ } else if (stylingWithinPreprocessor) {
+ if (IsASpaceOrTab(sc.ch)) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ } else if (sc.Match('/', '*') || sc.Match('/', '/') || sc.Match('&', '&')) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ }
+ break;
+ case SCE_FS_DISABLEDCODE:
+ if (sc.ch == '#' && visibleChars == 0) {
+ sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
+ do { // Skip whitespace between # and preprocessor word
+ sc.Forward();
+ } while (IsASpaceOrTab(sc.ch) && sc.More());
+ if (sc.MatchIgnoreCase("pragma")) {
+ sc.Forward(6);
+ do { // Skip more whitespace until keyword
+ sc.Forward();
+ } while (IsASpaceOrTab(sc.ch) && sc.More());
+ if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
+ bEnableCode = true;
+ sc.SetState(SCE_FS_DISABLEDCODE);
+ sc.Forward(sc.ch == '_' ? 8 : 6);
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ } else {
+ sc.ChangeState(SCE_FS_DISABLEDCODE);
+ }
+ } else {
+ sc.ChangeState(SCE_FS_DISABLEDCODE);
+ }
+ }
+ break;
+ case SCE_FS_DATE:
+ if (sc.ch == '}') {
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ } else if (sc.atLineEnd) {
+ sc.ChangeState(SCE_FS_STRINGEOL);
}
- sc.ForwardSetState(SCE_FS_DEFAULT);
- } else if (sc.atLineEnd) {
- sc.ChangeState(SCE_FS_STRINGEOL);
- sc.ForwardSetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_COMMENT) {
- if (sc.Match('*', '/')) { // new code
- sc.Forward();
- sc.ForwardSetState(SCE_FS_DEFAULT);
- //if (sc.atLineEnd) { // old code
- // sc.SetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_COMMENTLINE) { //new code
- if (sc.ch == '\r' || sc.ch == '\n') {
- sc.SetState(SCE_FS_DEFAULT);
- visibleChars = 0;
- }
- } else if (sc.state == SCE_FS_PREPROCESSOR) {
- if (sc.atLineEnd) {
- sc.SetState(SCE_FS_DEFAULT);
- }
- } else if (sc.state == SCE_FS_DATE) {
- if (sc.ch == '#' || !IsADateCharacter(sc.chNext)) {
- sc.ForwardSetState(SCE_FS_DEFAULT);
- }
}
// Determine if a new state should be entered.
- if (sc.state == SCE_FS_DEFAULT) {
- if (sc.Match('/', '*')) { // New code
- sc.SetState(SCE_FS_COMMENT);
- sc.Forward(); // Eat the * so it isn't used for the end of the comment
- //if (sc.ch == '\'') { // Old code
- // sc.SetState(SCE_FS_COMMENT); // old code
- } else if (sc.Match('/', '/')) { // New code
+ if (sc.state == SCE_FS_DEFAULT || sc.state == SCE_FS_DEFAULT_C) {
+ if (bEnableCode &&
+ (sc.MatchIgnoreCase(".and.") || sc.MatchIgnoreCase(".not."))) {
+ sc.SetState(SCE_FS_WORDOPERATOR);
+ sc.Forward(4);
+ } else if (bEnableCode && sc.MatchIgnoreCase(".or.")) {
+ sc.SetState(SCE_FS_WORDOPERATOR);
+ sc.Forward(3);
+ } else if (bEnableCode &&
+ (sc.MatchIgnoreCase(".t.") || sc.MatchIgnoreCase(".f.") ||
+ (!IsAWordChar(sc.GetRelative(3)) && sc.MatchIgnoreCase("nil")))) {
+ sc.SetState(SCE_FS_CONSTANT);
+ sc.Forward(2);
+ } else if (sc.Match('/', '*')) {
+ sc.SetState(bEnableCode ? SCE_FS_COMMENTDOC : SCE_FS_COMMENTDOC_C);
+ sc.Forward();
+ } else if (bEnableCode && sc.Match('&', '&')) {
sc.SetState(SCE_FS_COMMENTLINE);
- } else if (sc.ch == '\"') {
- sc.SetState(SCE_FS_STRING);
+ sc.Forward();
+ } else if (sc.Match('/', '/')) {
+ sc.SetState(bEnableCode ? SCE_FS_COMMENTLINEDOC : SCE_FS_COMMENTLINEDOC_C);
+ sc.Forward();
+ } else if (bEnableCode && sc.ch == '*' && visibleChars == 0) {
+ sc.SetState(SCE_FS_COMMENT);
+ } else if (sc.ch == '\"' || sc.ch == '\'') {
+ sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
+ closeStringChar = sc.ch;
+ } else if (closeStringChar == '>' && sc.ch == '<') {
+ sc.SetState(bEnableCode ? SCE_FS_STRING : SCE_FS_STRING_C);
} else if (sc.ch == '#' && visibleChars == 0) {
- // Preprocessor commands are alone on their line
- sc.SetState(SCE_FS_PREPROCESSOR);
- } else if (sc.ch == '#') {
- int n = 1;
- int chSeek = ' ';
- while ((n < 100) && (chSeek == ' ' || chSeek == '\t')) {
- chSeek = sc.GetRelative(n);
- n++;
- }
- if (IsADigit(chSeek)) {
+ sc.SetState(bEnableCode ? SCE_FS_PREPROCESSOR : SCE_FS_PREPROCESSOR_C);
+ do { // Skip whitespace between # and preprocessor word
+ sc.Forward();
+ } while (IsASpaceOrTab(sc.ch) && sc.More());
+ if (sc.atLineEnd) {
+ sc.SetState(bEnableCode ? SCE_FS_DEFAULT : SCE_FS_DEFAULT_C);
+ } else if (sc.MatchIgnoreCase("include")) {
+ if (stylingWithinPreprocessor) {
+ closeStringChar = '>';
+ }
+ } else if (sc.MatchIgnoreCase("pragma")) {
+ sc.Forward(6);
+ do { // Skip more whitespace until keyword
+ sc.Forward();
+ } while (IsASpaceOrTab(sc.ch) && sc.More());
+ if (sc.MatchIgnoreCase("begindump") || sc.MatchIgnoreCase("__cstream")) {
+ bEnableCode = false;
+ if (stylingWithinPreprocessor) {
+ sc.SetState(SCE_FS_DISABLEDCODE);
+ sc.Forward(8);
+ sc.ForwardSetState(SCE_FS_DEFAULT_C);
+ } else {
+ sc.SetState(SCE_FS_DISABLEDCODE);
+ }
+ } else if (sc.MatchIgnoreCase("enddump") || sc.MatchIgnoreCase("__endtext")) {
+ bEnableCode = true;
+ sc.SetState(SCE_FS_DISABLEDCODE);
+ sc.Forward(sc.ch == '_' ? 8 : 6);
+ sc.ForwardSetState(SCE_FS_DEFAULT);
+ }
+ }
+ } else if (bEnableCode && sc.ch == '{') {
+ int p = 0;
+ int chSeek;
+ unsigned int endPos(startPos + length);
+ do { // Skip whitespace
+ chSeek = sc.GetRelative(++p);
+ } while (IsASpaceOrTab(chSeek) && (sc.currentPos + p < endPos));
+ if (chSeek == '^') {
sc.SetState(SCE_FS_DATE);
} else {
sc.SetState(SCE_FS_OPERATOR);
}
- } else if (sc.ch == '&' && tolower(sc.chNext) == 'h') {
- sc.SetState(SCE_FS_NUMBER);
- } else if (sc.ch == '&' && tolower(sc.chNext) == 'o') {
- sc.SetState(SCE_FS_NUMBER);
} else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_FS_NUMBER);
- } else if (IsAWordStart(sc.ch) || (sc.ch == '[')) {
- sc.SetState(SCE_FS_IDENTIFIER);
- } else if (isoperator(static_cast<char>(sc.ch)) || (sc.ch == '\\')) {
- sc.SetState(SCE_FS_OPERATOR);
+ sc.SetState(bEnableCode ? SCE_FS_NUMBER : SCE_FS_NUMBER_C);
+ } else if (IsAWordChar(sc.ch)) {
+ sc.SetState(bEnableCode ? SCE_FS_IDENTIFIER : SCE_FS_IDENTIFIER_C);
+ } else if (isoperator(static_cast<char>(sc.ch)) || (bEnableCode && sc.ch == '@')) {
+ sc.SetState(bEnableCode ? SCE_FS_OPERATOR : SCE_FS_OPERATOR_C);
}
}
if (sc.atLineEnd) {
visibleChars = 0;
+ closeStringChar = 0;
}
if (!IsASpace(sc.ch)) {
visibleChars++;
@@ -173,36 +303,33 @@ static void ColouriseFlagShipDoc(unsigned int startPos, int length, int initStyl
}
static void FoldFlagShipDoc(unsigned int startPos, int length, int,
- WordList *[], Accessor &styler) {
+ WordList *[], Accessor &styler)
+{
int endPos = startPos + length;
// Backtrack to previous line in case need to fix its fold status
int lineCurrent = styler.GetLine(startPos);
- if (startPos > 0) {
- if (lineCurrent > 0) {
+ if (startPos > 0 && lineCurrent > 0) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
- }
}
int spaceFlags = 0;
- int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags, IsFlagShipComment);
+ int indentCurrent = styler.IndentAmount(lineCurrent, &spaceFlags);
char chNext = styler[startPos];
for (int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos-1)) {
int lev = indentCurrent;
- int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags, IsFlagShipComment);
+ int indentNext = styler.IndentAmount(lineCurrent + 1, &spaceFlags);
if (!(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
- // Only non whitespace lines can be headers
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
} else if (indentNext & SC_FOLDLEVELWHITEFLAG) {
- // Line after is blank so check the next - maybe should continue further?
int spaceFlags2 = 0;
- int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2, IsFlagShipComment);
+ int indentNext2 = styler.IndentAmount(lineCurrent + 2, &spaceFlags2);
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext2 & SC_FOLDLEVELNUMBERMASK)) {
lev |= SC_FOLDLEVELHEADERFLAG;
}
@@ -215,16 +342,13 @@ static void FoldFlagShipDoc(unsigned int startPos, int length, int,
}
}
-
static const char * const FSWordListDesc[] = {
- "Keywords",
- "functions",
- "user2",
- "user3",
+ "Keywords Commands",
+ "Std Library Functions",
+ "Procedure, return, exit",
+ "Class (oop)",
+ "Doxygen keywords",
0
};
LexerModule lmFlagShip(SCLEX_FLAGSHIP, ColouriseFlagShipDoc, "flagship", FoldFlagShipDoc, FSWordListDesc);
-
-
-
diff --git a/plugins/scintilla/scintilla/LexForth.cxx b/plugins/scintilla/scintilla/LexForth.cxx
index e52543f..0e9875c 100644
--- a/plugins/scintilla/scintilla/LexForth.cxx
+++ b/plugins/scintilla/scintilla/LexForth.cxx
@@ -7,18 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -130,7 +133,7 @@ static void ColouriseForthDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_FORTH_NUMBER);
while(sc.More() && isascii(sc.chNext) && (sc.chNext == '0' || sc.chNext == '1'))
sc.Forward();
- } else if ( isascii(sc.ch) &&
+ } else if ( isascii(sc.ch) &&
(isxdigit(sc.ch) || ((sc.ch == '.' || sc.ch == '-') && isascii(sc.chNext) && isxdigit(sc.chNext)) )
){
sc.SetState(SCE_FORTH_NUMBER);
@@ -173,4 +176,4 @@ static const char * const forthWordLists[] = {
LexerModule lmForth(SCLEX_FORTH, ColouriseForthDoc, "forth", FoldForthDoc, forthWordLists);
-
+
diff --git a/plugins/scintilla/scintilla/LexFortran.cxx b/plugins/scintilla/scintilla/LexFortran.cxx
index 0b3f277..6c61c54 100644
--- a/plugins/scintilla/scintilla/LexFortran.cxx
+++ b/plugins/scintilla/scintilla/LexFortran.cxx
@@ -8,18 +8,23 @@
/***************************************/
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
/***************************************/
-#include "Platform.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.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
@@ -261,7 +266,7 @@ static int classifyFoldPointFortran(const char* s, const char* prevWord, const c
|| strcmp(s, "endmodule") == 0 || strcmp(s, "endprogram") == 0
|| strcmp(s, "endsubroutine") == 0 || strcmp(s, "endtype") == 0
|| strcmp(s, "endwhere") == 0
- || strcmp(s, "procedure") == 0 ) { // Take care of the module procedure statement
+ || (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;
diff --git a/plugins/scintilla/scintilla/LexGAP.cxx b/plugins/scintilla/scintilla/LexGAP.cxx
index 25bd33b..fb30660 100644
--- a/plugins/scintilla/scintilla/LexGAP.cxx
+++ b/plugins/scintilla/scintilla/LexGAP.cxx
@@ -8,25 +8,28 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
static inline bool IsGAPOperator(char ch) {
- if (isalnum(ch)) return false;
+ if (isascii(ch) && isalnum(ch)) return false;
if (ch == '+' || ch == '-' || ch == '*' || ch == '/' ||
ch == '^' || ch == ',' || ch == '!' || ch == '.' ||
ch == '=' || ch == '<' || ch == '>' || ch == '(' ||
diff --git a/plugins/scintilla/scintilla/LexGen.py b/plugins/scintilla/scintilla/LexGen.py
new file mode 100755
index 0000000..22cdaae
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexGen.py
@@ -0,0 +1,304 @@
+#!/usr/bin/env python
+# LexGen.py - implemented 2002 by Neil Hodgson neilh scintilla org
+# Released to the public domain.
+
+# Regenerate the Scintilla and SciTE source files that list
+# all the lexers and all the properties files.
+# Should be run whenever a new lexer is added or removed.
+# Requires Python 2.4 or later
+# Most files are regenerated in place with templates stored in comments.
+# The VS .NET project file is generated into a different file as the
+# VS .NET environment will not retain comments when modifying the file.
+# The files are copied to a string apart from sections between a
+# ++Autogenerated comment and a --Autogenerated comment which is
+# generated by the CopyWithInsertion function. After the whole
+# string is instantiated, it is compared with the target file and
+# if different the file is rewritten.
+# Does not regenerate the Visual C++ 6 project files but does the VS .NET
+# project file.
+
+import string
+import sys
+import os
+import glob
+
+# EOL constants
+CR = "\r"
+LF = "\n"
+CRLF = "\r\n"
+if sys.platform == "win32":
+ NATIVE = CRLF
+else:
+ # Yes, LF is the native EOL even on Mac OS X. CR is just for
+ # Mac OS <=9 (a.k.a. "Mac Classic")
+ NATIVE = LF
+
+# Automatically generated sections contain start and end comments,
+# a definition line and the results.
+# The results are replaced by regenerating based on the definition line.
+# The definition line is a comment prefix followed by "**".
+# If there is a digit after the ** then this indicates which list to use
+# and the digit and next character are not part of the definition
+# Backslash is used as an escape within the definition line.
+# The part between \( and \) is repeated for each item in the list.
+# \* is replaced by each list item. \t, and \n are tab and newline.
+def CopyWithInsertion(input, commentPrefix, retainDefs, eolType, *lists):
+ copying = 1
+ listid = 0
+ output = []
+ for line in input.splitlines(0):
+ isStartGenerated = line.startswith(commentPrefix + "++Autogenerated")
+ if copying and not isStartGenerated:
+ output.append(line)
+ if isStartGenerated:
+ if retainDefs:
+ output.append(line)
+ copying = 0
+ definition = ""
+ elif not copying and line.startswith(commentPrefix + "**"):
+ if retainDefs:
+ output.append(line)
+ definition = line[len(commentPrefix + "**"):]
+ if (commentPrefix == "<!--") and (" -->" in definition):
+ definition = definition.replace(" -->", "")
+ listid = 0
+ if definition[0] in string.digits:
+ listid = int(definition[:1])
+ definition = definition[2:]
+ # Hide double slashes as a control character
+ definition = definition.replace("\\\\", "\001")
+ # Do some normal C style transforms
+ definition = definition.replace("\\n", "\n")
+ definition = definition.replace("\\t", "\t")
+ # Get the doubled backslashes back as single backslashes
+ definition = definition.replace("\001", "\\")
+ startRepeat = definition.find("\\(")
+ endRepeat = definition.find("\\)")
+ intro = definition[:startRepeat]
+ out = ""
+ if intro.endswith("\n"):
+ pos = 0
+ else:
+ pos = len(intro)
+ out += intro
+ middle = definition[startRepeat+2:endRepeat]
+ for i in lists[listid]:
+ item = middle.replace("\\*", i)
+ if pos and (pos + len(item) >= 80):
+ out += "\\\n"
+ pos = 0
+ out += item
+ pos += len(item)
+ if item.endswith("\n"):
+ pos = 0
+ outro = definition[endRepeat+2:]
+ out += outro
+ out = out.replace("\n", eolType) # correct EOLs in generated content
+ output.append(out)
+ elif line.startswith(commentPrefix + "--Autogenerated"):
+ copying = 1
+ if retainDefs:
+ output.append(line)
+ output = [line.rstrip(" \t") for line in output] # trim trailing whitespace
+ return eolType.join(output) + eolType
+
+def UpdateFile(filename, updated):
+ """ If the file is different to updated then copy updated
+ into the file else leave alone so CVS and make don't treat
+ it as modified. """
+ try:
+ infile = open(filename, "rb")
+ except IOError: # File is not there yet
+ out = open(filename, "wb")
+ out.write(updated.encode('utf-8'))
+ out.close()
+ print("New %s" % filename)
+ return
+ original = infile.read()
+ infile.close()
+ original = original.decode('utf-8')
+ if updated != original:
+ os.unlink(filename)
+ out = open(filename, "wb")
+ out.write(updated.encode('utf-8'))
+ out.close()
+ print("Changed %s " % filename)
+ #~ else:
+ #~ print "Unchanged", filename
+
+def Generate(inpath, outpath, commentPrefix, eolType, *lists):
+ """Generate 'outpath' from 'inpath'.
+
+ "eolType" indicates the type of EOLs to use in the generated
+ file. It should be one of following constants: LF, CRLF,
+ CR, or NATIVE.
+ """
+ #print "generate '%s' -> '%s' (comment prefix: %r, eols: %r)"\
+ # % (inpath, outpath, commentPrefix, eolType)
+ try:
+ infile = open(inpath, "rb")
+ except IOError:
+ print("Can not open %s" % inpath)
+ return
+ original = infile.read()
+ infile.close()
+ original = original.decode('utf-8')
+ updated = CopyWithInsertion(original, commentPrefix,
+ inpath == outpath, eolType, *lists)
+ UpdateFile(outpath, updated)
+
+def Regenerate(filename, commentPrefix, eolType, *lists):
+ """Regenerate the given file.
+
+ "eolType" indicates the type of EOLs to use in the generated
+ file. It should be one of following constants: LF, CRLF,
+ CR, or NATIVE.
+ """
+ Generate(filename, filename, commentPrefix, eolType, *lists)
+
+def FindModules(lexFile):
+ modules = []
+ f = open(lexFile)
+ for l in f.readlines():
+ if l.startswith("LexerModule"):
+ l = l.replace("(", " ")
+ modules.append(l.split()[1])
+ return modules
+
+# Properties that start with lexer. or fold. are automatically found but there are some
+# older properties that don't follow this pattern so must be explicitly listed.
+knownIrregularProperties = [
+ "fold",
+ "styling.within.preprocessor",
+ "tab.timmy.whinge.level",
+ "asp.default.language",
+ "html.tags.case.sensitive",
+ "ps.level",
+ "ps.tokenize",
+ "sql.backslash.escapes",
+ "nsis.uservars",
+ "nsis.ignorecase"
+]
+
+def FindProperties(lexFile):
+ properties = {}
+ f = open(lexFile)
+ for l in f.readlines():
+ if ("GetProperty" in l or "DefineProperty" in l) and "\"" in l:
+ l = l.strip()
+ if not l.startswith("//"): # Drop comments
+ propertyName = l.split("\"")[1]
+ if propertyName.lower() == propertyName:
+ # Only allow lower case property names
+ if propertyName in knownIrregularProperties or \
+ propertyName.startswith("fold.") or \
+ propertyName.startswith("lexer."):
+ properties[propertyName] = 1
+ return properties
+
+def FindPropertyDocumentation(lexFile):
+ documents = {}
+ f = open(lexFile)
+ name = ""
+ for l in f.readlines():
+ l = l.strip()
+ if "// property " in l:
+ propertyName = l.split()[2]
+ if propertyName.lower() == propertyName:
+ # Only allow lower case property names
+ name = propertyName
+ documents[name] = ""
+ elif "DefineProperty" in l and "\"" in l:
+ propertyName = l.split("\"")[1]
+ if propertyName.lower() == propertyName:
+ # Only allow lower case property names
+ name = propertyName
+ documents[name] = ""
+ elif name:
+ if l.startswith("//"):
+ if documents[name]:
+ documents[name] += " "
+ documents[name] += l[2:].strip()
+ elif l.startswith("\""):
+ l = l[1:].strip()
+ if l.endswith(";"):
+ l = l[:-1].strip()
+ if l.endswith(")"):
+ l = l[:-1].strip()
+ if l.endswith("\""):
+ l = l[:-1]
+ # Fix escaped double quotes
+ l = l.replace("\\\"", "\"")
+ documents[name] += l
+ else:
+ name = ""
+ for name in list(documents.keys()):
+ if documents[name] == "":
+ del documents[name]
+ return documents
+
+def ciCompare(a,b):
+ return cmp(a.lower(), b.lower())
+
+def ciKey(a):
+ return a.lower()
+
+def sortListInsensitive(l):
+ try: # Try key function
+ l.sort(key=ciKey)
+ except TypeError: # Earlier version of Python, so use comparison function
+ l.sort(ciCompare)
+
+def RegenerateAll():
+ root="../../"
+
+ # Find all the lexer source code files
+ lexFilePaths = glob.glob(root + "scintilla/lexers/Lex*.cxx")
+ sortListInsensitive(lexFilePaths)
+ lexFiles = [os.path.basename(f)[:-4] for f in lexFilePaths]
+ print(lexFiles)
+ lexerModules = []
+ lexerProperties = {}
+ propertyDocuments = {}
+ for lexFile in lexFilePaths:
+ lexerModules.extend(FindModules(lexFile))
+ for k in FindProperties(lexFile).keys():
+ lexerProperties[k] = 1
+ documents = FindPropertyDocumentation(lexFile)
+ for k in documents.keys():
+ propertyDocuments[k] = documents[k]
+ sortListInsensitive(lexerModules)
+ del lexerProperties["fold.comment.python"]
+ lexerProperties = list(lexerProperties.keys())
+ sortListInsensitive(lexerProperties)
+
+ # Generate HTML to document each property
+ # This is done because tags can not be safely put inside comments in HTML
+ documentProperties = list(propertyDocuments.keys())
+ sortListInsensitive(documentProperties)
+ propertiesHTML = []
+ for k in documentProperties:
+ propertiesHTML.append("\t<tr>\n\t<td>%s</td>\n\t<td>%s</td>\n\t</tr>" %
+ (k, propertyDocuments[k]))
+
+ # Find all the SciTE properties files
+ otherProps = ["abbrev.properties", "Embedded.properties", "SciTEGlobal.properties", "SciTE.properties"]
+ if os.path.exists(root + "scite"):
+ propFilePaths = glob.glob(root + "scite/src/*.properties")
+ sortListInsensitive(propFilePaths)
+ propFiles = [os.path.basename(f) for f in propFilePaths if os.path.basename(f) not in otherProps]
+ sortListInsensitive(propFiles)
+ print(propFiles)
+
+ Regenerate(root + "scintilla/src/Catalogue.cxx", "//", NATIVE, lexerModules)
+ Regenerate(root + "scintilla/win32/scintilla.mak", "#", NATIVE, lexFiles)
+ Regenerate(root + "scintilla/win32/scintilla_vc6.mak", "#", NATIVE, lexFiles)
+ if os.path.exists(root + "scite"):
+ Regenerate(root + "scite/win32/makefile", "#", NATIVE, propFiles)
+ Regenerate(root + "scite/win32/scite.mak", "#", NATIVE, propFiles)
+ Regenerate(root + "scite/src/SciTEProps.cxx", "//", NATIVE, lexerProperties)
+ Regenerate(root + "scite/doc/SciTEDoc.html", "<!--", NATIVE, propertiesHTML)
+ Generate(root + "scite/boundscheck/vcproj.gen",
+ root + "scite/boundscheck/SciTE.vcproj", "#", NATIVE, lexFiles)
+
+RegenerateAll()
diff --git a/plugins/scintilla/scintilla/LexGui4Cli.cxx b/plugins/scintilla/scintilla/LexGui4Cli.cxx
index 1c92de7..13cf9ea 100644
--- a/plugins/scintilla/scintilla/LexGui4Cli.cxx
+++ b/plugins/scintilla/scintilla/LexGui4Cli.cxx
@@ -23,18 +23,21 @@ val SCE_GC_OPERATOR=9
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexHTML.cxx b/plugins/scintilla/scintilla/LexHTML.cxx
index 6038326..4c50a15 100644
--- a/plugins/scintilla/scintilla/LexHTML.cxx
+++ b/plugins/scintilla/scintilla/LexHTML.cxx
@@ -7,19 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -54,13 +56,6 @@ inline bool IsOperator(int ch) {
return false;
}
-static inline int MakeLowerCase(int ch) {
- if (ch < 'A' || ch > 'Z')
- return ch;
- else
- return ch - 'A' + 'a';
-}
-
static void GetTextSegment(Accessor &styler, unsigned int start, unsigned int end, char *s, size_t len) {
size_t i = 0;
for (; (i < end - start + 1) && (i < len-1); i++) {
@@ -76,12 +71,12 @@ static const char *GetNextWord(Accessor &styler, unsigned int start, char *s, si
char ch = static_cast<char>(styler.SafeGetCharAt(start + i));
if ((i == 0) && !IsAWordStart(ch))
break;
- if ((i > 0) && !IsAWordChar(ch))
+ if ((i > 0) && !IsAWordChar(ch))
break;
s[i] = ch;
}
s[i] = '\0';
-
+
return s;
}
@@ -323,19 +318,19 @@ static int classifyTagHTML(unsigned int start, unsigned int end,
static void classifyWordHTJS(unsigned int start, unsigned int end,
WordList &keywords, Accessor &styler, script_mode inScriptType) {
+ char s[30 + 1];
+ unsigned int i = 0;
+ for (; i < end - start + 1 && i < 30; i++) {
+ s[i] = styler[start + i];
+ }
+ s[i] = '\0';
+
char chAttr = SCE_HJ_WORD;
- bool wordIsNumber = IsADigit(styler[start]) || (styler[start] == '.');
- if (wordIsNumber)
+ bool wordIsNumber = IsADigit(s[0]) || ((s[0] == '.') && IsADigit(s[1]));
+ if (wordIsNumber) {
chAttr = SCE_HJ_NUMBER;
- else {
- char s[30 + 1];
- unsigned int i = 0;
- for (; i < end - start + 1 && i < 30; i++) {
- s[i] = styler[start + i];
- }
- s[i] = '\0';
- if (keywords.InList(s))
- chAttr = SCE_HJ_KEYWORD;
+ } else if (keywords.InList(s)) {
+ chAttr = SCE_HJ_KEYWORD;
}
styler.ColourTo(end, statePrintForState(chAttr, inScriptType));
}
@@ -494,7 +489,7 @@ static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType
if (strlen(blockType) == 0) {
return ((ch == '%') && (chNext == '>'));
} else if ((0 == strcmp(blockType, "inherit")) ||
- (0 == strcmp(blockType, "namespace")) ||
+ (0 == strcmp(blockType, "namespace")) ||
(0 == strcmp(blockType, "include")) ||
(0 == strcmp(blockType, "page"))) {
return ((ch == '/') && (chNext == '>'));
@@ -507,6 +502,18 @@ static bool isMakoBlockEnd(const int ch, const int chNext, const char *blockType
}
}
+static bool isDjangoBlockEnd(const int ch, const int chNext, const char *blockType) {
+ if (strlen(blockType) == 0) {
+ return 0;
+ } else if (0 == strcmp(blockType, "%")) {
+ return ((ch == '%') && (chNext == '}'));
+ } else if (0 == strcmp(blockType, "{")) {
+ return ((ch == '}') && (chNext == '}'));
+ } else {
+ return 0;
+ }
+}
+
static bool isPHPStringState(int state) {
return
(state == SCE_HPHP_HSTRING) ||
@@ -575,14 +582,14 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.StartAt(startPos, static_cast<char>(STYLE_MAX));
char prevWord[200];
prevWord[0] = '\0';
- char nextWord[200];
- nextWord[0] = '\0';
char phpStringDelimiter[200]; // PHP is not limited in length, we are
phpStringDelimiter[0] = '\0';
int StateToPrint = initStyle;
int state = stateForPrintState(StateToPrint);
char makoBlockType[200];
makoBlockType[0] = '\0';
+ char djangoBlockType[2];
+ djangoBlockType[0] = '\0';
// If inside a tag, it may be a script tag, so reread from the start to ensure any language tags are seen
if (InTagState(state)) {
@@ -607,13 +614,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
int lineCurrent = styler.GetLine(startPos);
int lineState;
if (lineCurrent > 0) {
- lineState = styler.GetLineState(lineCurrent);
+ lineState = styler.GetLineState(lineCurrent-1);
} else {
// Default client and ASP scripting language is JavaScript
lineState = eScriptJS << 8;
- // property asp.default.language
- // Script in ASP code is initially assumed to be in JavaScript.
+ // property asp.default.language
+ // Script in ASP code is initially assumed to be in JavaScript.
// To change this to VBScript set asp.default.language to 2. Python is 3.
lineState |= styler.GetPropertyInt("asp.default.language", eScriptJS) << 4;
}
@@ -630,44 +637,49 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (inScriptType == eNonHtmlScript && state == SCE_H_COMMENT) {
scriptLanguage = eScriptComment;
}
+ script_type beforeLanguage = ScriptOfState(beforePreProc);
- // property fold.html
- // Folding is turned on or off for HTML and XML files with this option.
+ // property fold.html
+ // Folding is turned on or off for HTML and XML files with this option.
// The fold option must also be on for folding to occur.
const bool foldHTML = styler.GetPropertyInt("fold.html", 0) != 0;
const bool fold = foldHTML && styler.GetPropertyInt("fold", 0);
- // property fold.html.preprocessor
- // Folding is turned on or off for scripts embedded in HTML files with this option.
+ // property fold.html.preprocessor
+ // Folding is turned on or off for scripts embedded in HTML files with this option.
// The default is on.
const bool foldHTMLPreprocessor = foldHTML && styler.GetPropertyInt("fold.html.preprocessor", 1);
const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- // property fold.hypertext.comment
- // Allow folding for comments in scripts embedded in HTML.
- // The default is off.
+ // property fold.hypertext.comment
+ // Allow folding for comments in scripts embedded in HTML.
+ // The default is off.
const bool foldComment = fold && styler.GetPropertyInt("fold.hypertext.comment", 0) != 0;
- // property fold.hypertext.heredoc
- // Allow folding for heredocs in scripts embedded in HTML.
- // The default is off.
+ // property fold.hypertext.heredoc
+ // Allow folding for heredocs in scripts embedded in HTML.
+ // The default is off.
const bool foldHeredoc = fold && styler.GetPropertyInt("fold.hypertext.heredoc", 0) != 0;
- // property html.tags.case.sensitive
- // For XML and HTML, setting this property to 1 will make tags match in a case
- // sensitive way which is the expected behaviour for XML and XHTML.
+ // property html.tags.case.sensitive
+ // For XML and HTML, setting this property to 1 will make tags match in a case
+ // sensitive way which is the expected behaviour for XML and XHTML.
const bool caseSensitive = styler.GetPropertyInt("html.tags.case.sensitive", 0) != 0;
- // property lexer.xml.allow.scripts
- // Set to 0 to disable scripts in XML.
+ // property lexer.xml.allow.scripts
+ // Set to 0 to disable scripts in XML.
const bool allowScripts = styler.GetPropertyInt("lexer.xml.allow.scripts", 1) != 0;
- // property lexer.html.mako
- // Set to 1 to enable the mako template language.
+ // property lexer.html.mako
+ // Set to 1 to enable the mako template language.
const bool isMako = styler.GetPropertyInt("lexer.html.mako", 0) != 0;
+ // property lexer.html.django
+ // Set to 1 to enable the django template language.
+ const bool isDjango = styler.GetPropertyInt("lexer.html.django", 0) != 0;
+
const CharacterSet setHTMLWord(CharacterSet::setAlphaNum, ".-_:!#", 0x80, true);
const CharacterSet setTagContinue(CharacterSet::setAlphaNum, ".-_:!#[", 0x80, true);
const CharacterSet setAttributeContinue(CharacterSet::setAlphaNum, ".-_:!#/", 0x80, true);
@@ -732,8 +744,18 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if ((state != SCE_HPHP_COMMENT) && (state != SCE_HPHP_COMMENTLINE) && (state != SCE_HJ_COMMENT) && (state != SCE_HJ_COMMENTLINE) && (state != SCE_HJ_COMMENTDOC) && (!isStringState(state))) {
//Platform::DebugPrintf("state=%d, StateToPrint=%d, initStyle=%d\n", state, StateToPrint, initStyle);
//if ((state == SCE_HPHP_OPERATOR) || (state == SCE_HPHP_DEFAULT) || (state == SCE_HJ_SYMBOLS) || (state == SCE_HJ_START) || (state == SCE_HJ_DEFAULT)) {
- if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
- levelCurrent += ((ch == '{') || (ch == '/')) ? 1 : -1;
+ if (ch == '#') {
+ int j = i + 1;
+ while ((j < lengthDoc) && IsASpaceOrTab(styler.SafeGetCharAt(j))) {
+ j++;
+ }
+ if (styler.Match(j, "region") || styler.Match(j, "if")) {
+ levelCurrent++;
+ } else if (styler.Match(j, "end")) {
+ levelCurrent--;
+ }
+ } else if ((ch == '{') || (ch == '}') || (foldComment && (ch == '/') && (chNext == '*'))) {
+ levelCurrent += (((ch == '{') || (ch == '/')) ? 1 : -1);
}
} else if (((state == SCE_HPHP_COMMENT) || (state == SCE_HJ_COMMENT)) && foldComment && (ch == '*') && (chNext == '/')) {
levelCurrent--;
@@ -785,8 +807,6 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
visibleChars = 0;
levelPrev = levelCurrent;
}
- lineCurrent++;
- lineStartVisibleChars = 0;
styler.SetLineState(lineCurrent,
((inScriptType & 0x03) << 0) |
((tagOpened & 0x01) << 2) |
@@ -794,13 +814,15 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
((aspScript & 0x0F) << 4) |
((clientScript & 0x0F) << 8) |
((beforePreProc & 0xFF) << 12));
+ lineCurrent++;
+ lineStartVisibleChars = 0;
}
// Allow falling through to mako handling code if newline is going to end a block
if (((ch == '\r' && chNext != '\n') || (ch == '\n')) &&
(!isMako || (0 != strcmp(makoBlockType, "%")))) {
}
-
+
// generic end of script processing
else if ((inScriptType == eNonHtmlScript) && (ch == '<') && (chNext == '/')) {
// Check if it's the end of the script tag (or any other HTML tag)
@@ -857,9 +879,11 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
else if ((state != SCE_H_ASPAT) &&
!isPHPStringState(state) &&
(state != SCE_HPHP_COMMENT) &&
+ (state != SCE_HPHP_COMMENTLINE) &&
(ch == '<') &&
(chNext == '?') &&
- !IsScriptCommentState(state) ) {
+ !IsScriptCommentState(state)) {
+ beforeLanguage = scriptLanguage;
scriptLanguage = segIsScriptingIndicator(styler, i + 2, i + 6, eScriptPHP);
if (scriptLanguage != eScriptPHP && isStringState(state)) continue;
styler.ColourTo(i - 1, StateToPrint);
@@ -886,13 +910,13 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
}
// handle the start Mako template Python code
- else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
+ else if (isMako && scriptLanguage == eScriptNone && ((ch == '<' && chNext == '%') ||
(lineStartVisibleChars == 1 && ch == '%') ||
(ch == '$' && chNext == '{') ||
(ch == '<' && chNext == '/' && chNext2 == '%'))) {
if (ch == '%')
strcpy(makoBlockType, "%");
- else if (ch == '$')
+ else if (ch == '$')
strcpy(makoBlockType, "{");
else if (chNext == '/')
GetNextWord(styler, i+3, makoBlockType, sizeof(makoBlockType));
@@ -917,7 +941,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
styler.ColourTo(i, SCE_H_ASP);
if (foldHTMLPreprocessor && ch == '<')
levelCurrent++;
-
+
if (ch != '%' && ch != '$') {
i += strlen(makoBlockType);
visibleChars += strlen(makoBlockType);
@@ -931,8 +955,62 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue;
}
+ // handle the start/end of Django comment
+ else if (isDjango && state != SCE_H_COMMENT && (ch == '{' && chNext == '#')) {
+ styler.ColourTo(i - 1, StateToPrint);
+ beforePreProc = state;
+ beforeLanguage = scriptLanguage;
+ if (inScriptType == eNonHtmlScript)
+ inScriptType = eNonHtmlScriptPreProc;
+ else
+ inScriptType = eNonHtmlPreProc;
+ i += 1;
+ visibleChars += 1;
+ scriptLanguage = eScriptComment;
+ state = SCE_H_COMMENT;
+ styler.ColourTo(i, SCE_H_ASP);
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ continue;
+ } else if (isDjango && state == SCE_H_COMMENT && (ch == '#' && chNext == '}')) {
+ styler.ColourTo(i - 1, StateToPrint);
+ i += 1;
+ visibleChars += 1;
+ styler.ColourTo(i, SCE_H_ASP);
+ state = beforePreProc;
+ if (inScriptType == eNonHtmlScriptPreProc)
+ inScriptType = eNonHtmlScript;
+ else
+ inScriptType = eHtml;
+ scriptLanguage = beforeLanguage;
+ continue;
+ }
+
+ // handle the start Django template code
+ else if (isDjango && scriptLanguage != eScriptPython && (ch == '{' && (chNext == '%' || chNext == '{'))) {
+ if (chNext == '%')
+ strcpy(djangoBlockType, "%");
+ else
+ strcpy(djangoBlockType, "{");
+ styler.ColourTo(i - 1, StateToPrint);
+ beforePreProc = state;
+ if (inScriptType == eNonHtmlScript)
+ inScriptType = eNonHtmlScriptPreProc;
+ else
+ inScriptType = eNonHtmlPreProc;
+
+ i += 1;
+ visibleChars += 1;
+ state = SCE_HP_START;
+ beforeLanguage = scriptLanguage;
+ scriptLanguage = eScriptPython;
+ styler.ColourTo(i, SCE_H_ASP);
+
+ ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
+ continue;
+ }
+
// handle the start of ASP pre-processor = Non-HTML
- else if (!isMako && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
+ else if (!isMako && !isDjango && !isCommentASPState(state) && (ch == '<') && (chNext == '%') && !isPHPStringState(state)) {
styler.ColourTo(i - 1, StateToPrint);
beforePreProc = state;
if (inScriptType == eNonHtmlScript)
@@ -977,7 +1055,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
(ch == '!') &&
(StateToPrint != SCE_H_CDATA) &&
(!IsCommentState(StateToPrint)) &&
- (!IsScriptCommentState(StateToPrint)) ) {
+ (!IsScriptCommentState(StateToPrint))) {
beforePreProc = state;
styler.ColourTo(i - 2, StateToPrint);
if ((chNext == '-') && (chNext2 == '-')) {
@@ -998,8 +1076,8 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
}
// handle the end of Mako Python code
- else if (isMako &&
- ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+ else if (isMako &&
+ ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
(scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
isMakoBlockEnd(ch, chNext, makoBlockType)) {
if (state == SCE_H_ASPAT) {
@@ -1030,8 +1108,34 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
continue;
}
+ // handle the end of Django template code
+ else if (isDjango &&
+ ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+ (scriptLanguage != eScriptNone) && stateAllowsTermination(state) &&
+ isDjangoBlockEnd(ch, chNext, djangoBlockType)) {
+ if (state == SCE_H_ASPAT) {
+ aspScript = segIsScriptingIndicator(styler,
+ styler.GetStartSegment(), i - 1, aspScript);
+ }
+ if (state == SCE_HP_WORD) {
+ classifyWordHTPy(styler.GetStartSegment(), i - 1, keywords4, styler, prevWord, inScriptType);
+ } else {
+ styler.ColourTo(i - 1, StateToPrint);
+ }
+ i += 1;
+ visibleChars += 1;
+ styler.ColourTo(i, SCE_H_ASP);
+ state = beforePreProc;
+ if (inScriptType == eNonHtmlScriptPreProc)
+ inScriptType = eNonHtmlScript;
+ else
+ inScriptType = eHtml;
+ scriptLanguage = beforeLanguage;
+ continue;
+ }
+
// handle the end of a pre-processor = Non-HTML
- else if ((!isMako && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
+ else if ((!isMako && !isDjango && ((inScriptType == eNonHtmlPreProc) || (inScriptType == eNonHtmlScriptPreProc)) &&
(((scriptLanguage != eScriptNone) && stateAllowsTermination(state))) &&
(((ch == '%') || (ch == '?')) && (chNext == '>'))) ||
((scriptLanguage == eScriptSGML) && (ch == '>') && (state != SCE_H_SGML_COMMENT))) {
@@ -1081,7 +1185,7 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
if (foldHTMLPreprocessor && (scriptLanguage != eScriptXML)) {
levelCurrent--;
}
- scriptLanguage = eScriptNone;
+ scriptLanguage = beforeLanguage;
continue;
}
/////////////////////////////////////
@@ -1564,7 +1668,9 @@ static void ColouriseHyperTextDoc(unsigned int startPos, int length, int initSty
i += 2;
} else if (isLineEnd(ch)) {
styler.ColourTo(i - 1, StateToPrint);
- state = SCE_HJ_STRINGEOL;
+ if (chPrev != '\\' && (chPrev2 != '\\' || chPrev != '\r' || ch != '\n')) {
+ state = SCE_HJ_STRINGEOL;
+ }
}
break;
case SCE_HJ_STRINGEOL:
diff --git a/plugins/scintilla/scintilla/LexHaskell.cxx b/plugins/scintilla/scintilla/LexHaskell.cxx
index b528f3f..37d85d0 100644
--- a/plugins/scintilla/scintilla/LexHaskell.cxx
+++ b/plugins/scintilla/scintilla/LexHaskell.cxx
@@ -7,6 +7,7 @@
*
* Written by Tobias Engvall - tumm at dtek dot chalmers dot se
*
+ * Several bug fixes by Krasimir Angelov - kr.angelov at gmail.com
*
* TODO:
* * Implement a folder :)
@@ -18,19 +19,22 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -45,11 +49,13 @@ using namespace Scintilla;
#endif
-// Max level of nested comments
-#define SCE_HA_COMMENTMAX SCE_HA_COMMENTBLOCK3
-
-
-enum kwType { kwOther, kwClass, kwData, kwInstance, kwImport, kwModule, kwType};
+#define HA_MODE_DEFAULT 0
+#define HA_MODE_IMPORT1 1
+#define HA_MODE_IMPORT2 2
+#define HA_MODE_IMPORT3 3
+#define HA_MODE_MODULE 4
+#define HA_MODE_FFI 5
+#define HA_MODE_TYPE 6
static inline bool IsNewline(const int ch) {
return (ch == '\n' || ch == '\r');
@@ -73,146 +79,234 @@ static void ColorizeHaskellDoc(unsigned int startPos, int length, int initStyle,
WordList *keywordlists[], Accessor &styler) {
WordList &keywords = *keywordlists[0];
-
- int kwLast = kwOther;
+ WordList &ffi = *keywordlists[1];
StyleContext sc(startPos, length, initStyle, styler);
- for (; sc.More(); sc.Forward()) {
+ int lineCurrent = styler.GetLine(startPos);
+ int state = lineCurrent ? styler.GetLineState(lineCurrent-1)
+ : HA_MODE_DEFAULT;
+ int mode = state & 0xF;
+ int xmode = state >> 4;
+ while (sc.More()) {
// Check for state end
+
// Operator
if (sc.state == SCE_HA_OPERATOR) {
- kwLast = kwOther;
- sc.SetState(SCE_HA_DEFAULT);
+ if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
+ sc.Forward();
+ } else {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ }
}
// String
else if (sc.state == SCE_HA_STRING) {
if (sc.ch == '\"') {
- sc.ForwardSetState(SCE_HA_DEFAULT);
+ sc.Forward();
+ styler.ColourTo(sc.currentPos-1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
} else if (sc.ch == '\\') {
- sc.Forward();
- }
+ sc.Forward(2);
+ } else if (sc.atLineEnd) {
+ styler.ColourTo(sc.currentPos-1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ } else {
+ sc.Forward();
+ }
}
// Char
else if (sc.state == SCE_HA_CHARACTER) {
if (sc.ch == '\'') {
- sc.ForwardSetState(SCE_HA_DEFAULT);
+ sc.Forward();
+ styler.ColourTo(sc.currentPos-1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
} else if (sc.ch == '\\') {
- sc.Forward();
- }
+ sc.Forward(2);
+ } else if (sc.atLineEnd) {
+ styler.ColourTo(sc.currentPos-1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ } else {
+ sc.Forward();
+ }
}
// Number
else if (sc.state == SCE_HA_NUMBER) {
- if (!IsADigit(sc.ch)) {
- sc.SetState(SCE_HA_DEFAULT);
- }
- }
- // Types, constructors, etc.
- else if (sc.state == SCE_HA_CAPITAL) {
- if (!IsAWordChar(sc.ch) || sc.ch == '.') {
- sc.SetState(SCE_HA_DEFAULT);
+ if (IsADigit(sc.ch, xmode)) {
+ sc.Forward();
+ } else if ((xmode == 10) &&
+ (sc.ch == 'e' || sc.ch == 'E') &&
+ (IsADigit(sc.chNext) || sc.chNext == '+' || sc.chNext == '-')) {
+ sc.Forward();
+ if (sc.ch == '+' || sc.ch == '-')
+ sc.Forward();
+ } else {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
}
}
// Identifier
else if (sc.state == SCE_HA_IDENTIFIER) {
- if (!IsAWordChar(sc.ch)) {
+ if (IsAWordChar(sc.ch)) {
+ sc.Forward();
+ } else {
char s[100];
sc.GetCurrent(s, sizeof(s));
- int style = SCE_HA_IDENTIFIER;
- if ((kwLast == kwImport) || (strcmp(s,"qualified") == 0) || (strcmp(s,"as") == 0)) {
- style = SCE_HA_IMPORT;
- } else if (keywords.InList(s)) {
+ int style = sc.state;
+ int new_mode = 0;
+ if (keywords.InList(s)) {
style = SCE_HA_KEYWORD;
- } else if (kwLast == kwData) {
- style = SCE_HA_DATA;
- } else if (kwLast == kwClass) {
- style = SCE_HA_CLASS;
- } else if (kwLast == kwModule) {
- style = SCE_HA_MODULE;
} else if (isupper(s[0])) {
- style = SCE_HA_CAPITAL;
- }
- sc.ChangeState(style);
- sc.SetState(SCE_HA_DEFAULT);
- if (style == SCE_HA_KEYWORD) {
- if (0 == strcmp(s, "class"))
- kwLast = kwClass;
- else if (0 == strcmp(s, "data"))
- kwLast = kwData;
- else if (0 == strcmp(s, "instance"))
- kwLast = kwInstance;
- else if (0 == strcmp(s, "import"))
- kwLast = kwImport;
- else if (0 == strcmp(s, "module"))
- kwLast = kwModule;
+ if (mode >= HA_MODE_IMPORT1 && mode <= HA_MODE_IMPORT3) {
+ style = SCE_HA_MODULE;
+ new_mode = HA_MODE_IMPORT2;
+ } else if (mode == HA_MODE_MODULE)
+ style = SCE_HA_MODULE;
else
- kwLast = kwOther;
- } else if (style == SCE_HA_CLASS || style == SCE_HA_IMPORT ||
- style == SCE_HA_MODULE || style == SCE_HA_CAPITAL ||
- style == SCE_HA_DATA || style == SCE_HA_INSTANCE) {
- kwLast = kwOther;
+ style = SCE_HA_CAPITAL;
+ } else if (mode == HA_MODE_IMPORT1 &&
+ strcmp(s,"qualified") == 0) {
+ style = SCE_HA_KEYWORD;
+ new_mode = HA_MODE_IMPORT1;
+ } else if (mode == HA_MODE_IMPORT2) {
+ if (strcmp(s,"as") == 0) {
+ style = SCE_HA_KEYWORD;
+ new_mode = HA_MODE_IMPORT3;
+ } else if (strcmp(s,"hiding") == 0) {
+ style = SCE_HA_KEYWORD;
+ }
+ } else if (mode == HA_MODE_FFI) {
+ if (ffi.InList(s)) {
+ style = SCE_HA_KEYWORD;
+ new_mode = HA_MODE_FFI;
+ }
}
+ else if (mode == HA_MODE_TYPE) {
+ if (strcmp(s,"family") == 0)
+ style = SCE_HA_KEYWORD;
+ }
+ styler.ColourTo(sc.currentPos - 1, style);
+ if (strcmp(s,"import") == 0 && mode != HA_MODE_FFI)
+ new_mode = HA_MODE_IMPORT1;
+ else if (strcmp(s,"module") == 0)
+ new_mode = HA_MODE_MODULE;
+ else if (strcmp(s,"foreign") == 0)
+ new_mode = HA_MODE_FFI;
+ else if (strcmp(s,"type") == 0)
+ new_mode = HA_MODE_TYPE;
+ sc.ChangeState(SCE_HA_DEFAULT);
+ mode = new_mode;
}
}
+
// Comments
// Oneliner
else if (sc.state == SCE_HA_COMMENTLINE) {
- if (IsNewline(sc.ch))
- sc.SetState(SCE_HA_DEFAULT);
+ if (sc.atLineEnd) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ } else {
+ sc.Forward();
+ }
}
// Nested
- else if (sc.state >= SCE_HA_COMMENTBLOCK) {
+ else if (sc.state == SCE_HA_COMMENTBLOCK) {
if (sc.Match("{-")) {
- if (sc.state < SCE_HA_COMMENTMAX)
- sc.SetState(sc.state + 1);
+ sc.Forward(2);
+ xmode++;
}
else if (sc.Match("-}")) {
+ sc.Forward(2);
+ xmode--;
+ if (xmode == 0) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_DEFAULT);
+ }
+ } else {
+ if (sc.atLineEnd) {
+ // Remember the line state for future incremental lexing
+ styler.SetLineState(lineCurrent, (xmode << 4) | mode);
+ lineCurrent++;
+ }
sc.Forward();
- if (sc.state == SCE_HA_COMMENTBLOCK)
- sc.ForwardSetState(SCE_HA_DEFAULT);
- else
- sc.ForwardSetState(sc.state - 1);
}
}
// New state?
if (sc.state == SCE_HA_DEFAULT) {
// Digit
- if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
- sc.SetState(SCE_HA_NUMBER);
- if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) { // Match anything starting with "0x" or "0X", too
- sc.Forward(1);
- }
+ if (IsADigit(sc.ch) ||
+ (sc.ch == '.' && IsADigit(sc.chNext)) ||
+ (sc.ch == '-' && IsADigit(sc.chNext))) {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.ChangeState(SCE_HA_NUMBER);
+ if (sc.ch == '0' && (sc.chNext == 'X' || sc.chNext == 'x')) {
+ // Match anything starting with "0x" or "0X", too
+ sc.Forward(2);
+ xmode = 16;
+ } else if (sc.ch == '0' && (sc.chNext == 'O' || sc.chNext == 'o')) {
+ // Match anything starting with "0x" or "0X", too
+ sc.Forward(2);
+ xmode = 8;
+ } else {
+ sc.Forward();
+ xmode = 10;
+ }
+ mode = HA_MODE_DEFAULT;
}
// Comment line
else if (sc.Match("--")) {
- sc.SetState(SCE_HA_COMMENTLINE);
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward(2);
+ sc.ChangeState(SCE_HA_COMMENTLINE);
// Comment block
}
else if (sc.Match("{-")) {
- sc.SetState(SCE_HA_COMMENTBLOCK);
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward(2);
+ sc.ChangeState(SCE_HA_COMMENTBLOCK);
+ xmode = 1;
}
// String
else if (sc.Match('\"')) {
- sc.SetState(SCE_HA_STRING);
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ sc.ChangeState(SCE_HA_STRING);
}
// Character
else if (sc.Match('\'')) {
- sc.SetState(SCE_HA_CHARACTER);
- }
- // Stringstart
- else if (sc.Match('\"')) {
- sc.SetState(SCE_HA_STRING);
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ sc.ChangeState(SCE_HA_CHARACTER);
}
+ else if (sc.ch == '(' || sc.ch == ')' ||
+ sc.ch == '{' || sc.ch == '}' ||
+ sc.ch == '[' || sc.ch == ']') {
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ styler.ColourTo(sc.currentPos - 1, SCE_HA_OPERATOR);
+ mode = HA_MODE_DEFAULT;
+ }
// Operator
else if (isascii(sc.ch) && isoperator(static_cast<char>(sc.ch))) {
- sc.SetState(SCE_HA_OPERATOR);
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ sc.ChangeState(SCE_HA_OPERATOR);
+ mode = HA_MODE_DEFAULT;
}
// Keyword
else if (IsAWordStart(sc.ch)) {
- sc.SetState(SCE_HA_IDENTIFIER);
+ styler.ColourTo(sc.currentPos - 1, sc.state);
+ sc.Forward();
+ sc.ChangeState(SCE_HA_IDENTIFIER);
+ } else {
+ if (sc.atLineEnd) {
+ // Remember the line state for future incremental lexing
+ styler.SetLineState(lineCurrent, (xmode << 4) | mode);
+ lineCurrent++;
+ }
+ sc.Forward();
}
-
}
}
sc.Complete();
@@ -272,4 +366,3 @@ void EXT_LEXER_DECL GetLexerName(unsigned int Index, char *name, int buflength)
#endif
LexerModule lmHaskell(SCLEX_HASKELL, ColorizeHaskellDoc, "haskell");
-
diff --git a/plugins/scintilla/scintilla/LexInno.cxx b/plugins/scintilla/scintilla/LexInno.cxx
index 6d1102c..a0f5b32 100644
--- a/plugins/scintilla/scintilla/LexInno.cxx
+++ b/plugins/scintilla/scintilla/LexInno.cxx
@@ -7,19 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "CharClassify.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -34,7 +36,6 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
char *buffer = new char[length];
int bufferCount = 0;
bool isBOL, isEOL, isWS, isBOLWS = 0;
- bool isCode = false;
bool isCStyleComment = false;
WordList §ionKeywords = *keywordLists[0];
@@ -44,6 +45,10 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
WordList &pascalKeywords = *keywordLists[4];
WordList &userKeywords = *keywordLists[5];
+ int curLine = styler.GetLine(startPos);
+ int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : 0;
+ bool isCode = (curLineState == 1);
+
// Go through all provided text segment
// using the hand-written state machine shown below
styler.StartAt(startPos);
@@ -64,6 +69,12 @@ static void ColouriseInnoDoc(unsigned int startPos, int length, int, WordList *k
isEOL = (ch == '\n' || ch == '\r');
isWS = (ch == ' ' || ch == '\t');
+ if ((ch == '\r' && chNext != '\n') || (ch == '\n')) {
+ // Remember the line state for future incremental lexing
+ curLine = styler.GetLine(i);
+ styler.SetLineState(curLine, (isCode ? 1 : 0));
+ }
+
switch(state) {
case SCE_INNO_DEFAULT:
if (!isCode && ch == ';' && isBOLWS) {
diff --git a/plugins/scintilla/scintilla/LexKix.cxx b/plugins/scintilla/scintilla/LexKix.cxx
index 06e7c17..32af263 100644
--- a/plugins/scintilla/scintilla/LexKix.cxx
+++ b/plugins/scintilla/scintilla/LexKix.cxx
@@ -7,18 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexLisp.cxx b/plugins/scintilla/scintilla/LexLisp.cxx
old mode 100755
new mode 100644
index e1d06cb..08f765a
--- a/plugins/scintilla/scintilla/LexLisp.cxx
+++ b/plugins/scintilla/scintilla/LexLisp.cxx
@@ -8,18 +8,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
@@ -44,7 +47,7 @@ static inline bool isLispwordstart(char ch) {
static void classifyWordLisp(unsigned int start, unsigned int end, WordList &keywords, WordList &keywords_kw, Accessor &styler) {
- PLATFORM_ASSERT(end >= start);
+ assert(end >= start);
char s[100];
unsigned int i;
bool digit_flag = true;
@@ -139,7 +142,7 @@ static void ColouriseLispDoc(unsigned int startPos, int length, int initStyle, W
}
}
} else if (state == SCE_LISP_MACRO_DISPATCH) {
- if (!isdigit(ch)) {
+ if (!(isascii(ch) && isdigit(ch))) {
if (ch != 'r' && ch != 'R' && (i - styler.GetStartSegment()) > 1) {
state = SCE_LISP_DEFAULT;
} else {
diff --git a/plugins/scintilla/scintilla/LexLout.cxx b/plugins/scintilla/scintilla/LexLout.cxx
index 492e4ed..985b93b 100644
--- a/plugins/scintilla/scintilla/LexLout.cxx
+++ b/plugins/scintilla/scintilla/LexLout.cxx
@@ -7,18 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexLua.cxx b/plugins/scintilla/scintilla/LexLua.cxx
index a1e579f..1dc9d40 100644
--- a/plugins/scintilla/scintilla/LexLua.cxx
+++ b/plugins/scintilla/scintilla/LexLua.cxx
@@ -9,19 +9,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -59,8 +61,9 @@ static void ColouriseLuaDoc(
CharacterSet setWordStart(CharacterSet::setAlpha, "_", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
// Not exactly following number definition (several dots are seen as OK, etc.)
- // but probably enough in most cases.
- CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefABCDEF");
+ // but probably enough in most cases. [pP] is for hex floats.
+ CharacterSet setNumber(CharacterSet::setDigits, ".-+abcdefpABCDEFP");
+ CharacterSet setExponent(CharacterSet::setNone, "eEpP");
CharacterSet setLuaOperator(CharacterSet::setNone, "*/-+()={}~[];<>,.^%:#");
CharacterSet setEscapeSkip(CharacterSet::setNone, "\"'\\");
@@ -68,12 +71,16 @@ static void ColouriseLuaDoc(
// Initialize long string [[ ... ]] or block comment --[[ ... ]] nesting level,
// if we are inside such a string. Block comment was introduced in Lua 5.0,
// blocks with separators [=[ ... ]=] in Lua 5.1.
+ // Continuation of a string (\* whitespace escaping) is controlled by stringWs.
int nestLevel = 0;
int sepCount = 0;
- if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT) {
+ int stringWs = 0;
+ if (initStyle == SCE_LUA_LITERALSTRING || initStyle == SCE_LUA_COMMENT ||
+ initStyle == SCE_LUA_STRING || initStyle == SCE_LUA_CHARACTER) {
int lineState = styler.GetLineState(currentLine - 1);
- nestLevel = lineState >> 8;
+ nestLevel = lineState >> 9;
sepCount = lineState & 0xFF;
+ stringWs = lineState & 0x100;
}
// Do not leak onto next line
@@ -93,8 +100,10 @@ static void ColouriseLuaDoc(
switch (sc.state) {
case SCE_LUA_LITERALSTRING:
case SCE_LUA_COMMENT:
- // Inside a literal string or block comment, we set the line state
- styler.SetLineState(currentLine, (nestLevel << 8) | sepCount);
+ case SCE_LUA_STRING:
+ case SCE_LUA_CHARACTER:
+ // Inside a literal string, block comment or string, we set the line state
+ styler.SetLineState(currentLine, (nestLevel << 9) | stringWs | sepCount);
break;
default:
// Reset the line state
@@ -123,11 +132,11 @@ static void ColouriseLuaDoc(
if (sc.state == SCE_LUA_OPERATOR) {
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.state == SCE_LUA_NUMBER) {
- // We stop the number definition on non-numerical non-dot non-eE non-sign non-hexdigit char
+ // We stop the number definition on non-numerical non-dot non-eEpP non-sign non-hexdigit char
if (!setNumber.Contains(sc.ch)) {
sc.SetState(SCE_LUA_DEFAULT);
} else if (sc.ch == '-' || sc.ch == '+') {
- if (sc.chPrev != 'E' && sc.chPrev != 'e')
+ if (!setExponent.Contains(sc.chPrev))
sc.SetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_IDENTIFIER) {
@@ -158,24 +167,38 @@ static void ColouriseLuaDoc(
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_STRING) {
+ if (stringWs) {
+ if (!IsASpace(sc.ch))
+ stringWs = 0;
+ }
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
+ } else if (sc.chNext == '*') {
+ sc.Forward();
+ stringWs = 0x100;
}
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
- } else if (sc.atLineEnd) {
+ } else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
} else if (sc.state == SCE_LUA_CHARACTER) {
+ if (stringWs) {
+ if (!IsASpace(sc.ch))
+ stringWs = 0;
+ }
if (sc.ch == '\\') {
if (setEscapeSkip.Contains(sc.chNext)) {
sc.Forward();
+ } else if (sc.chNext == '*') {
+ sc.Forward();
+ stringWs = 0x100;
}
} else if (sc.ch == '\'') {
sc.ForwardSetState(SCE_LUA_DEFAULT);
- } else if (sc.atLineEnd) {
+ } else if (stringWs == 0 && sc.atLineEnd) {
sc.ChangeState(SCE_LUA_STRINGEOL);
sc.ForwardSetState(SCE_LUA_DEFAULT);
}
@@ -212,8 +235,10 @@ static void ColouriseLuaDoc(
sc.SetState(SCE_LUA_IDENTIFIER);
} else if (sc.ch == '\"') {
sc.SetState(SCE_LUA_STRING);
+ stringWs = 0;
} else if (sc.ch == '\'') {
sc.SetState(SCE_LUA_CHARACTER);
+ stringWs = 0;
} else if (sc.ch == '[') {
sepCount = LongDelimCheck(sc);
if (sepCount == 0) {
diff --git a/plugins/scintilla/scintilla/LexMMIXAL.cxx b/plugins/scintilla/scintilla/LexMMIXAL.cxx
index a00f35c..59bb9fd 100644
--- a/plugins/scintilla/scintilla/LexMMIXAL.cxx
+++ b/plugins/scintilla/scintilla/LexMMIXAL.cxx
@@ -9,18 +9,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -32,7 +35,7 @@ static inline bool IsAWordChar(const int ch) {
}
inline bool isMMIXALOperator(char ch) {
- if (isalnum(ch))
+ if (isascii(ch) && isalnum(ch))
return false;
if (ch == '+' || ch == '-' || ch == '|' || ch == '^' ||
ch == '*' || ch == '/' || ch == '/' ||
diff --git a/plugins/scintilla/scintilla/LexMPT.cxx b/plugins/scintilla/scintilla/LexMPT.cxx
index b0099ff..c09ac7a 100644
--- a/plugins/scintilla/scintilla/LexMPT.cxx
+++ b/plugins/scintilla/scintilla/LexMPT.cxx
@@ -7,21 +7,25 @@
// Copyright 2003 by Marius Gheorghe <mgheorghe cabletest com>
// The License.txt file describes the conditions under which this software may be distributed.
+#include <stdlib.h>
#include <string.h>
#include <stdio.h>
-#include <ctype.h>
-#include <stdlib.h>
+#include <stdarg.h>
+#include <assert.h>
#include <string>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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
@@ -32,7 +36,7 @@ static int GetLotLineState(std::string &line) {
// Now finds the first non-blank character
unsigned i; // Declares counter here to make it persistent after the for loop
for (i = 0; i < line.length(); ++i) {
- if (!isspace(line[i]))
+ if (!(isascii(line[i]) && isspace(line[i])))
break;
}
@@ -66,7 +70,7 @@ static int GetLotLineState(std::string &line) {
return SCE_LOT_ABORT;
}
else {
- return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;
+ return i ? SCE_LOT_PASS : SCE_LOT_DEFAULT;
}
}
}
@@ -135,10 +139,10 @@ static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Acc
if (ch == '\r' && chNext == '\n') {
// TO DO:
// Should really get the state of the previous line from the styler
- int stylePrev = style;
+ int stylePrev = style;
style = styleNext;
styleNext = styler.StyleAt(i + 2);
-
+
switch (style) {
/*
case SCE_LOT_SET:
@@ -147,7 +151,7 @@ static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Acc
*/
case SCE_LOT_FAIL:
/*
- if (stylePrev != SCE_LOT_FAIL)
+ if (stylePrev != SCE_LOT_FAIL)
lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
else
lev = SC_FOLDLEVELBASE + 1;
@@ -156,7 +160,7 @@ static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Acc
break;
default:
- if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)
+ if (lineCurrent == 0 || stylePrev == SCE_LOT_FAIL)
lev = SC_FOLDLEVELBASE | SC_FOLDLEVELHEADERFLAG;
else
lev = SC_FOLDLEVELBASE + 1;
@@ -166,7 +170,7 @@ static void FoldLotDoc(unsigned int startPos, int length, int, WordList *[], Acc
break;
}
- if (lev != styler.LevelAt(lineCurrent))
+ if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
lineCurrent++;
diff --git a/plugins/scintilla/scintilla/LexMSSQL.cxx b/plugins/scintilla/scintilla/LexMSSQL.cxx
index 4a3f3be..ce60039 100644
--- a/plugins/scintilla/scintilla/LexMSSQL.cxx
+++ b/plugins/scintilla/scintilla/LexMSSQL.cxx
@@ -7,18 +7,22 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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
diff --git a/plugins/scintilla/scintilla/LexMagik.cxx b/plugins/scintilla/scintilla/LexMagik.cxx
index c6f6585..45390d4 100644
--- a/plugins/scintilla/scintilla/LexMagik.cxx
+++ b/plugins/scintilla/scintilla/LexMagik.cxx
@@ -8,18 +8,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexMarkdown.cxx b/plugins/scintilla/scintilla/LexMarkdown.cxx
index f7fc48f..3937120 100644
--- a/plugins/scintilla/scintilla/LexMarkdown.cxx
+++ b/plugins/scintilla/scintilla/LexMarkdown.cxx
@@ -2,31 +2,31 @@
* LexMarkdown.cxx
*
* A simple Markdown lexer for scintilla.
- *
+ *
* Includes highlighting for some extra features from the
- * Pandoc implementation; strikeout, using '#.' as a default
+ * Pandoc implementation; strikeout, using '#.' as a default
* ordered list item marker, and delimited code blocks.
- *
+ *
* Limitations:
- *
+ *
* Standard indented code blocks are not highlighted at all,
- * as it would conflict with other indentation schemes. Use
+ * as it would conflict with other indentation schemes. Use
* delimited code blocks for blanket highlighting of an
* entire code block. Embedded HTML is not highlighted either.
* Blanket HTML highlighting has issues, because some Markdown
* implementations allow Markdown markup inside of the HTML. Also,
- * there is a following blank line issue that can't be ignored,
- * explained in the next paragraph. Embedded HTML and code
- * blocks would be better supported with language specific
+ * there is a following blank line issue that can't be ignored,
+ * explained in the next paragraph. Embedded HTML and code
+ * blocks would be better supported with language specific
* highlighting.
- *
+ *
* The highlighting aims to accurately reflect correct syntax,
* but a few restrictions are relaxed. Delimited code blocks are
- * highlighted, even if the line following the code block is not blank.
+ * highlighted, even if the line following the code block is not blank.
* Requiring a blank line after a block, breaks the highlighting
* in certain cases, because of the way Scintilla ends up calling
* the lexer.
- *
+ *
* Written by Jon Strait - jstrait moonloop net
*
* The License.txt file describes the conditions under which this
@@ -34,20 +34,22 @@
*
*****************************************************************/
-#include <stdlib.h>
+#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -74,7 +76,7 @@ static bool FollowToLineEnd(const int ch, const int state, const unsigned int en
else return false;
}
-// Set the state on text section from current to length characters,
+// Set the state on text section from current to length characters,
// then set the rest until the newline to default, except for any characters matching token
static void SetStateAndZoom(const int state, const int length, const int token, StyleContext &sc) {
sc.SetState(state);
@@ -100,9 +102,9 @@ static void SetStateAndZoom(const int state, const int length, const int token,
static bool HasPrevLineContent(StyleContext &sc) {
int i = 0;
// Go back to the previous newline
- while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i)))
+ while ((--i + (int)sc.currentPos) >= 0 && !IsNewline(sc.GetRelative(i)))
;
- while (--i + sc.currentPos) {
+ while ((--i + (int)sc.currentPos) >= 0) {
if (IsNewline(sc.GetRelative(i)))
break;
if (!IsASpaceOrTab(sc.GetRelative(i)))
@@ -116,12 +118,12 @@ static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
unsigned int i = 0;
while (++i) {
c = sc.GetRelative(i);
- if (c == sc.ch)
+ if (c == sc.ch)
++count;
// hit a terminating character
else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
// Are we a valid HRULE
- if ((IsNewline(c) || sc.currentPos + i == endPos) &&
+ if ((IsNewline(c) || sc.currentPos + i == endPos) &&
count >= 3 && !HasPrevLineContent(sc)) {
sc.SetState(SCE_MARKDOWN_HRULE);
sc.Forward(i);
@@ -145,7 +147,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
// Useful in the corner case of having to start at the beginning file position
// in the default state.
bool freezeCursor = false;
-
+
StyleContext sc(startPos, length, initStyle, styler);
while (sc.More()) {
@@ -154,18 +156,18 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
sc.Forward();
continue;
}
-
+
// A blockquotes resets the line semantics
if (sc.state == SCE_MARKDOWN_BLOCKQUOTE)
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
-
+
// Conditional state-based actions
if (sc.state == SCE_MARKDOWN_CODE2) {
if (sc.Match("``") && sc.GetRelative(-2) != ' ') {
sc.Forward(2);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
- }
+ }
else if (sc.state == SCE_MARKDOWN_CODE) {
if (sc.ch == '`' && sc.chPrev != ' ')
sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
@@ -201,14 +203,14 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
sc.Forward(2);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
- }
- else if (sc.state == SCE_MARKDOWN_STRONG2) {
- if (sc.Match("__") && sc.chPrev != ' ') {
+ }
+ else if (sc.state == SCE_MARKDOWN_STRONG2) {
+ if (sc.Match("__") && sc.chPrev != ' ') {
sc.Forward(2);
sc.SetState(SCE_MARKDOWN_DEFAULT);
}
}
- // Emphasis
+ // Emphasis
else if (sc.state == SCE_MARKDOWN_EM1) {
if (sc.ch == '*' && sc.chPrev != ' ')
sc.ForwardSetState(SCE_MARKDOWN_DEFAULT);
@@ -281,7 +283,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
sc.SetState(SCE_MARKDOWN_PRECHAR);
}
}
-
+
// The header lasts until the newline
else if (sc.state == SCE_MARKDOWN_HEADER1 || sc.state == SCE_MARKDOWN_HEADER2 ||
sc.state == SCE_MARKDOWN_HEADER3 || sc.state == SCE_MARKDOWN_HEADER4 ||
@@ -289,7 +291,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
if (IsNewline(sc.ch))
sc.SetState(SCE_MARKDOWN_LINE_BEGIN);
}
-
+
// New state only within the initial whitespace
if (sc.state == SCE_MARKDOWN_PRECHAR) {
// Blockquote
@@ -300,8 +302,8 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
sc.SetState(SCE_MARKDOWN_CODEBK);
*/
- // HRule - Total of three or more hyphens, asterisks, or underscores
- // on a line by themselves
+ // HRule - Total of three or more hyphens, asterisks, or underscores
+ // on a line by themselves
else if ((sc.ch == '-' || sc.ch == '*' || sc.ch == '_') && IsValidHrule(endPos, sc))
;
// Unordered list
@@ -314,7 +316,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
int digitCount = 0;
while (IsADigit(sc.GetRelative(++digitCount)))
;
- if (sc.GetRelative(digitCount) == '.' &&
+ if (sc.GetRelative(digitCount) == '.' &&
IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
sc.SetState(SCE_MARKDOWN_OLIST_ITEM);
sc.Forward(digitCount + 1);
@@ -332,7 +334,7 @@ static void ColorizeMarkdownDoc(unsigned int startPos, int length, int initStyle
else
++precharCount;
}
-
+
// New state anywhere in doc
if (sc.state == SCE_MARKDOWN_DEFAULT) {
if (sc.atLineStart && sc.ch == '#') {
diff --git a/plugins/scintilla/scintilla/LexMatlab.cxx b/plugins/scintilla/scintilla/LexMatlab.cxx
index 4e467bd..0d2064e 100644
--- a/plugins/scintilla/scintilla/LexMatlab.cxx
+++ b/plugins/scintilla/scintilla/LexMatlab.cxx
@@ -12,18 +12,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexMetapost.cxx b/plugins/scintilla/scintilla/LexMetapost.cxx
index 6afc9d8..d049521 100644
--- a/plugins/scintilla/scintilla/LexMetapost.cxx
+++ b/plugins/scintilla/scintilla/LexMetapost.cxx
@@ -14,18 +14,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
@@ -326,11 +329,11 @@ static const char * const metapostWordListDesc[] = {
static int classifyFoldPointMetapost(const char* s,WordList *keywordlists[]) {
WordList& keywordsStart=*keywordlists[3];
WordList& keywordsStop1=*keywordlists[4];
-
+
if (keywordsStart.InList(s)) {return 1;}
else if (keywordsStop1.InList(s)) {return -1;}
return 0;
-
+
}
static int ParseMetapostWord(unsigned int pos, Accessor &styler, char *word)
@@ -344,11 +347,11 @@ static int ParseMetapostWord(unsigned int pos, Accessor &styler, char *word)
length++;
ch=styler.SafeGetCharAt(pos+length);
}
- word[length]=0;
+ word[length]=0;
return length;
}
-
-static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler)
+
+static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *keywordlists[], Accessor &styler)
{
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos+length;
@@ -357,9 +360,9 @@ static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *ke
int levelPrev=styler.LevelAt(lineCurrent) & SC_FOLDLEVELNUMBERMASK;
int levelCurrent=levelPrev;
char chNext=styler[startPos];
-
+
char buffer[100]="";
-
+
for (unsigned int i=startPos; i < endPos; i++) {
char ch=chNext;
chNext=styler.SafeGetCharAt(i+1);
@@ -371,7 +374,7 @@ static void FoldMetapostDoc(unsigned int startPos, int length, int, WordList *ke
ParseMetapostWord(i, styler, buffer);
levelCurrent += classifyFoldPointMetapost(buffer,keywordlists);
}
-
+
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
diff --git a/plugins/scintilla/scintilla/LexModula.cxx b/plugins/scintilla/scintilla/LexModula.cxx
new file mode 100644
index 0000000..1d03611
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexModula.cxx
@@ -0,0 +1,743 @@
+// -*- coding: utf-8 -*-
+// Scintilla source code edit control
+/**
+ * @file LexModula.cxx
+ * @author Dariusz "DKnoto" KnociÅ?ski
+ * @date 2011/02/03
+ * @brief Lexer for Modula-2/3 documents.
+ */
+// The License.txt file describes the conditions under which this software may
+// be distributed.
+
+#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 "PropSetSimple.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
+
+#ifdef DEBUG_LEX_MODULA
+#define DEBUG_STATE( p, c )\
+ fprintf( stderr, "Unknown state: currentPos = %d, char = '%c'\n", p, c );
+#else
+#define DEBUG_STATE( p, c )
+#endif
+
+static inline bool IsDigitOfBase( unsigned ch, unsigned base ) {
+ if( ch < '0' || ch > 'f' ) return false;
+ if( base <= 10 ) {
+ if( ch >= ( '0' + base ) ) return false;
+ } else {
+ if( ch > '9' ) {
+ unsigned nb = base - 10;
+ if( ( ch < 'A' ) || ( ch >= ( 'A' + nb ) ) ) {
+ if( ( ch < 'a' ) || ( ch >= ( 'a' + nb ) ) ) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+}
+
+static inline unsigned IsOperator( StyleContext & sc, WordList & op ) {
+ int i;
+ char s[3];
+
+ s[0] = sc.ch;
+ s[1] = sc.chNext;
+ s[2] = 0;
+ for( i = 0; i < op.len; i++ ) {
+ if( ( strlen( op.words[i] ) == 2 ) &&
+ ( s[0] == op.words[i][0] && s[1] == op.words[i][1] ) ) {
+ return 2;
+ }
+ }
+ s[1] = 0;
+ for( i = 0; i < op.len; i++ ) {
+ if( ( strlen( op.words[i] ) == 1 ) &&
+ ( s[0] == op.words[i][0] ) ) {
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static inline bool IsEOL( Accessor &styler, unsigned curPos ) {
+ unsigned ch = styler.SafeGetCharAt( curPos );
+ if( ( ch == '\r' && styler.SafeGetCharAt( curPos + 1 ) == '\n' ) ||
+ ( ch == '\n' ) ) {
+ return true;
+ }
+ return false;
+}
+
+static inline bool checkStatement(
+ Accessor &styler,
+ int &curPos,
+ const char *stt, bool spaceAfter = true ) {
+ int len = strlen( stt );
+ int i;
+ for( i = 0; i < len; i++ ) {
+ if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
+ return false;
+ }
+ }
+ if( spaceAfter ) {
+ if( ! isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
+ return false;
+ }
+ }
+ curPos += ( len - 1 );
+ return true;
+}
+
+static inline bool checkEndSemicolon(
+ Accessor &styler,
+ int &curPos, int endPos )
+{
+ const char *stt = "END";
+ int len = strlen( stt );
+ int i;
+ for( i = 0; i < len; i++ ) {
+ if( styler.SafeGetCharAt( curPos + i ) != stt[i] ) {
+ return false;
+ }
+ }
+ while( isspace( styler.SafeGetCharAt( curPos + i ) ) ) {
+ i++;
+ if( ( curPos + i ) >= endPos ) return false;
+ }
+ if( styler.SafeGetCharAt( curPos + i ) != ';' ) {
+ return false;
+ }
+ curPos += ( i - 1 );
+ return true;
+}
+
+static inline bool checkKeyIdentOper(
+
+ Accessor &styler,
+ int &curPos, int endPos,
+ const char *stt, const char etk ) {
+ int newPos = curPos;
+ if( ! checkStatement( styler, newPos, stt ) )
+ return false;
+ newPos++;
+ if( newPos >= endPos )
+ return false;
+ if( ! isspace( styler.SafeGetCharAt( newPos ) ) )
+ return false;
+ newPos++;
+ if( newPos >= endPos )
+ return false;
+ while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
+ newPos++;
+ if( newPos >= endPos )
+ return false;
+ }
+ if( ! isalpha( styler.SafeGetCharAt( newPos ) ) )
+ return false;
+ newPos++;
+ if( newPos >= endPos )
+ return false;
+ char ch;
+ ch = styler.SafeGetCharAt( newPos );
+ while( isalpha( ch ) || isdigit( ch ) || ch == '_' ) {
+ newPos++;
+ if( newPos >= endPos ) return false;
+ ch = styler.SafeGetCharAt( newPos );
+ }
+ while( isspace( styler.SafeGetCharAt( newPos ) ) ) {
+ newPos++;
+ if( newPos >= endPos ) return false;
+ }
+ if( styler.SafeGetCharAt( newPos ) != etk )
+ return false;
+ curPos = newPos;
+ return true;
+}
+
+static void FoldModulaDoc( unsigned int startPos,
+ int length,
+ int , WordList *[],
+ Accessor &styler)
+{
+ int curLine = styler.GetLine(startPos);
+ int curLevel = SC_FOLDLEVELBASE;
+ int endPos = startPos + length;
+ if( curLine > 0 )
+ curLevel = styler.LevelAt( curLine - 1 ) >> 16;
+ int curPos = startPos;
+ int style = styler.StyleAt( curPos );
+ int visChars = 0;
+ int nextLevel = curLevel;
+
+ while( curPos < endPos ) {
+ if( ! isspace( styler.SafeGetCharAt( curPos ) ) ) visChars++;
+
+ switch( style ) {
+ case SCE_MODULA_COMMENT:
+ if( checkStatement( styler, curPos, "(*" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "*)" ) )
+ nextLevel--;
+ break;
+
+ case SCE_MODULA_DOXYCOMM:
+ if( checkStatement( styler, curPos, "(**", false ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "*)" ) )
+ nextLevel--;
+ break;
+
+ case SCE_MODULA_KEYWORD:
+ if( checkStatement( styler, curPos, "IF" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "BEGIN" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "TRY" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "LOOP" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "FOR" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "WHILE" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "REPEAT" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "UNTIL" ) )
+ nextLevel--;
+ else
+ if( checkStatement( styler, curPos, "WITH" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "CASE" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "TYPECASE" ) )
+ nextLevel++;
+ else
+ if( checkStatement( styler, curPos, "LOCK" ) )
+ nextLevel++;
+ else
+ if( checkKeyIdentOper( styler, curPos, endPos, "PROCEDURE", '(' ) )
+ nextLevel++;
+ else
+ if( checkKeyIdentOper( styler, curPos, endPos, "END", ';' ) ) {
+ int cln = curLine;
+ int clv_old = curLevel;
+ int pos;
+ char ch;
+ int clv_new;
+ while( cln > 0 ) {
+ clv_new = styler.LevelAt( cln - 1 ) >> 16;
+ if( clv_new < clv_old ) {
+ nextLevel--;
+ pos = styler.LineStart( cln );
+ while( ( ch = styler.SafeGetCharAt( pos ) ) != '\n' ) {
+ if( ch == 'P' ) {
+ if( styler.StyleAt(pos) == SCE_MODULA_KEYWORD ) {
+ if( checkKeyIdentOper( styler, pos, endPos,
+ "PROCEDURE", '(' ) ) {
+ break;
+ }
+ }
+ }
+ pos++;
+ }
+ clv_old = clv_new;
+ }
+ cln--;
+ }
+ }
+ else
+ if( checkKeyIdentOper( styler, curPos, endPos, "END", '.' ) )
+ nextLevel--;
+ else
+ if( checkEndSemicolon( styler, curPos, endPos ) )
+ nextLevel--;
+ else {
+ while( styler.StyleAt( curPos + 1 ) == SCE_MODULA_KEYWORD )
+ curPos++;
+ }
+ break;
+
+ default:
+ break;
+ }
+
+ if( IsEOL( styler, curPos ) || ( curPos == endPos - 1 ) ) {
+ int efectiveLevel = curLevel | nextLevel << 16;
+ if( visChars == 0 )
+ efectiveLevel |= SC_FOLDLEVELWHITEFLAG;
+ if( curLevel < nextLevel )
+ efectiveLevel |= SC_FOLDLEVELHEADERFLAG;
+ if( efectiveLevel != styler.LevelAt(curLine) ) {
+ styler.SetLevel(curLine, efectiveLevel );
+ }
+ curLine++;
+ curLevel = nextLevel;
+ if( IsEOL( styler, curPos ) && ( curPos == endPos - 1 ) ) {
+ styler.SetLevel( curLine, ( curLevel | curLevel << 16)
+ | SC_FOLDLEVELWHITEFLAG);
+ }
+ visChars = 0;
+ }
+ curPos++;
+ style = styler.StyleAt( curPos );
+ }
+}
+
+static inline bool skipWhiteSpaces( StyleContext & sc ) {
+ while( isspace( sc.ch ) ) {
+ sc.SetState( SCE_MODULA_DEFAULT );
+ if( sc.More() )
+ sc.Forward();
+ else
+ return false;
+ }
+ return true;
+}
+
+static void ColouriseModulaDoc( unsigned int startPos,
+ int length,
+ int initStyle,
+ WordList *wl[],
+ Accessor &styler ) {
+ WordList& keyWords = *wl[0];
+ WordList& reservedWords = *wl[1];
+ WordList& operators = *wl[2];
+ WordList& pragmaWords = *wl[3];
+ WordList& escapeCodes = *wl[4];
+ WordList& doxyKeys = *wl[5];
+
+ const int BUFLEN = 128;
+
+ char buf[BUFLEN];
+ int i, kl;
+
+ int charPos = 0;
+
+ StyleContext sc( startPos, length, initStyle, styler );
+
+ while( sc.More() ) {
+ switch( sc.state ) {
+ case SCE_MODULA_DEFAULT:
+ if( ! skipWhiteSpaces( sc ) ) break;
+
+ if( sc.ch == '(' && sc.chNext == '*' ) {
+ if( sc.GetRelative(2) == '*' ) {
+ sc.SetState( SCE_MODULA_DOXYCOMM );
+ sc.Forward();
+ } else {
+ sc.SetState( SCE_MODULA_COMMENT );
+ }
+ sc.Forward();
+ }
+ else
+ if( isalpha( sc.ch ) ) {
+ if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
+ for( i = 0; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i);
+ if( !isalpha( buf[i] ) && !(buf[i] == '_') )
+ break;
+ }
+ kl = i;
+ buf[kl] = 0;
+
+ if( keyWords.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_KEYWORD );
+ sc.Forward( kl );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ else
+ if( reservedWords.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_RESERVED );
+ sc.Forward( kl );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ } else {
+ /** check procedure identifier */
+ }
+ } else {
+ for( i = 0; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i);
+ if( !isalpha( buf[i] ) &&
+ !isdigit( buf[i] ) &&
+ !(buf[i] == '_') )
+ break;
+ }
+ kl = i;
+ buf[kl] = 0;
+
+ sc.SetState( SCE_MODULA_DEFAULT );
+ sc.Forward( kl );
+ continue;
+ }
+ }
+ else
+ if( isdigit( sc.ch ) ) {
+ sc.SetState( SCE_MODULA_NUMBER );
+ continue;
+ }
+ else
+ if( sc.ch == '\"' ) {
+ sc.SetState( SCE_MODULA_STRING );
+ }
+ else
+ if( sc.ch == '\'' ) {
+ charPos = sc.currentPos;
+ sc.SetState( SCE_MODULA_CHAR );
+ }
+ else
+ if( sc.ch == '<' && sc.chNext == '*' ) {
+ sc.SetState( SCE_MODULA_PRAGMA );
+ sc.Forward();
+ } else {
+ unsigned len = IsOperator( sc, operators );
+ if( len > 0 ) {
+ sc.SetState( SCE_MODULA_OPERATOR );
+ sc.Forward( len );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ } else {
+ DEBUG_STATE( sc.currentPos, sc.ch );
+ }
+ }
+ break;
+
+ case SCE_MODULA_COMMENT:
+ if( sc.ch == '*' && sc.chNext == ')' ) {
+ sc.Forward( 2 );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ break;
+
+ case SCE_MODULA_DOXYCOMM:
+ switch( sc.ch ) {
+ case '*':
+ if( sc.chNext == ')' ) {
+ sc.Forward( 2 );
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ break;
+
+ case '@':
+ if( islower( sc.chNext ) ) {
+ for( i = 0; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i+1);
+ if( isspace( buf[i] ) ) break;
+ }
+ buf[i] = 0;
+ kl = i;
+
+ if( doxyKeys.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_DOXYKEY );
+ sc.Forward( kl + 1 );
+ sc.SetState( SCE_MODULA_DOXYCOMM );
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ break;
+
+ case SCE_MODULA_NUMBER:
+ {
+ buf[0] = sc.ch;
+ for( i = 1; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i);
+ if( ! isdigit( buf[i] ) )
+ break;
+ }
+ kl = i;
+ buf[kl] = 0;
+
+ switch( sc.GetRelative(kl) ) {
+ case '_':
+ {
+ int base = atoi( buf );
+ if( base < 2 || base > 16 ) {
+ sc.SetState( SCE_MODULA_BADSTR );
+ } else {
+ int imax;
+
+ kl++;
+ for( i = 0; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(kl+i);
+ if( ! IsDigitOfBase( buf[i], 16 ) ) {
+ break;
+ }
+ }
+ imax = i;
+ for( i = 0; i < imax; i++ ) {
+ if( ! IsDigitOfBase( buf[i], base ) ) {
+ sc.SetState( SCE_MODULA_BADSTR );
+ break;
+ }
+ }
+ kl += imax;
+ }
+ sc.SetState( SCE_MODULA_BASENUM );
+ for( i = 0; i < kl; i++ ) {
+ sc.Forward();
+ }
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ break;
+
+ case '.':
+ if( sc.GetRelative(kl+1) == '.' ) {
+ kl--;
+ for( i = 0; i < kl; i++ ) {
+ sc.Forward();
+ }
+ sc.Forward();
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ } else {
+ bool doNext = false;
+
+ kl++;
+
+ buf[0] = sc.GetRelative(kl);
+ if( isdigit( buf[0] ) ) {
+ for( i = 0;; i++ ) {
+ if( !isdigit(sc.GetRelative(kl+i)) )
+ break;
+ }
+ kl += i;
+ buf[0] = sc.GetRelative(kl);
+
+ switch( buf[0] )
+ {
+ case 'E':
+ case 'e':
+ case 'D':
+ case 'd':
+ case 'X':
+ case 'x':
+ kl++;
+ buf[0] = sc.GetRelative(kl);
+ if( buf[0] == '-' || buf[0] == '+' ) {
+ kl++;
+ }
+ buf[0] = sc.GetRelative(kl);
+ if( isdigit( buf[0] ) ) {
+ for( i = 0;; i++ ) {
+ if( !isdigit(sc.GetRelative(kl+i)) ) {
+ buf[0] = sc.GetRelative(kl+i);
+ break;
+ }
+ }
+ kl += i;
+ doNext = true;
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ break;
+
+ default:
+ doNext = true;
+ break;
+ }
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+
+ if( doNext ) {
+ if( ! isspace( buf[0] ) &&
+ buf[0] != ')' &&
+ buf[0] != '>' &&
+ buf[0] != '<' &&
+ buf[0] != '=' &&
+ buf[0] != '#' &&
+ buf[0] != '+' &&
+ buf[0] != '-' &&
+ buf[0] != '*' &&
+ buf[0] != '/' &&
+ buf[0] != ',' &&
+ buf[0] != ';'
+ ) {
+ sc.SetState( SCE_MODULA_BADSTR );
+ } else {
+ kl--;
+ }
+ }
+ }
+ sc.SetState( SCE_MODULA_FLOAT );
+ for( i = 0; i < kl; i++ ) {
+ sc.Forward();
+ }
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ break;
+
+ default:
+ for( i = 0; i < kl; i++ ) {
+ sc.Forward();
+ }
+ break;
+ }
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ break;
+
+ case SCE_MODULA_STRING:
+ if( sc.ch == '\"' ) {
+ sc.Forward();
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ } else {
+ if( sc.ch == '\\' ) {
+ i = 1;
+ if( IsDigitOfBase( sc.chNext, 8 ) ) {
+ for( i = 1; i < BUFLEN - 1; i++ ) {
+ if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
+ break;
+ }
+ if( i == 3 ) {
+ sc.SetState( SCE_MODULA_STRSPEC );
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ } else {
+ buf[0] = sc.chNext;
+ buf[1] = 0;
+
+ if( escapeCodes.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_STRSPEC );
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ }
+ sc.Forward(i+1);
+ sc.SetState( SCE_MODULA_STRING );
+ continue;
+ }
+ }
+ break;
+
+ case SCE_MODULA_CHAR:
+ if( sc.ch == '\'' ) {
+ sc.Forward();
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ else
+ if( ( sc.currentPos - charPos ) == 1 ) {
+ if( sc.ch == '\\' ) {
+ i = 1;
+ if( IsDigitOfBase( sc.chNext, 8 ) ) {
+ for( i = 1; i < BUFLEN - 1; i++ ) {
+ if( ! IsDigitOfBase(sc.GetRelative(i+1), 8 ) )
+ break;
+ }
+ if( i == 3 ) {
+ sc.SetState( SCE_MODULA_CHARSPEC );
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ } else {
+ buf[0] = sc.chNext;
+ buf[1] = 0;
+
+ if( escapeCodes.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_CHARSPEC );
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ }
+ }
+ sc.Forward(i+1);
+ sc.SetState( SCE_MODULA_CHAR );
+ continue;
+ }
+ } else {
+ sc.SetState( SCE_MODULA_BADSTR );
+ sc.Forward();
+ sc.SetState( SCE_MODULA_CHAR );
+ continue;
+ }
+ break;
+
+ case SCE_MODULA_PRAGMA:
+ if( sc.ch == '*' && sc.chNext == '>' ) {
+ sc.Forward();
+ sc.Forward();
+ sc.SetState( SCE_MODULA_DEFAULT );
+ continue;
+ }
+ else
+ if( isupper( sc.ch ) && isupper( sc.chNext ) ) {
+ buf[0] = sc.ch;
+ buf[1] = sc.chNext;
+ for( i = 2; i < BUFLEN - 1; i++ ) {
+ buf[i] = sc.GetRelative(i);
+ if( !isupper( buf[i] ) )
+ break;
+ }
+ kl = i;
+ buf[kl] = 0;
+ if( pragmaWords.InList( buf ) ) {
+ sc.SetState( SCE_MODULA_PRGKEY );
+ sc.Forward( kl );
+ sc.SetState( SCE_MODULA_PRAGMA );
+ continue;
+ }
+ }
+ break;
+
+ default:
+ break;
+ }
+ sc.Forward();
+ }
+ sc.Complete();
+}
+
+static const char *const modulaWordListDesc[] =
+{
+ "Keywords",
+ "ReservedKeywords",
+ "Operators",
+ "PragmaKeyswords",
+ "EscapeCodes",
+ "DoxygeneKeywords",
+ 0
+};
+
+LexerModule lmModula( SCLEX_MODULA, ColouriseModulaDoc, "modula", FoldModulaDoc,
+ modulaWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexMySQL.cxx b/plugins/scintilla/scintilla/LexMySQL.cxx
index e8496ce..305fa74 100644
--- a/plugins/scintilla/scintilla/LexMySQL.cxx
+++ b/plugins/scintilla/scintilla/LexMySQL.cxx
@@ -12,18 +12,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -113,12 +116,12 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
if (!IsAWordChar(sc.ch))
{
CheckForKeyword(sc, keywordlists);
-
+
// Additional check for function keywords needed.
// A function name must be followed by an opening parenthesis.
if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
sc.ChangeState(SCE_MYSQL_DEFAULT);
-
+
sc.SetState(SCE_MYSQL_DEFAULT);
}
break;
@@ -137,7 +140,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
if (keywordlists[4]->InList(&s[2]))
sc.ChangeState(SCE_MYSQL_KNOWNSYSTEMVARIABLE);
delete [] s;
-
+
sc.SetState(SCE_MYSQL_DEFAULT);
}
break;
@@ -232,7 +235,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
if (sc.Match('/', '*'))
{
sc.SetState(SCE_MYSQL_COMMENT);
-
+
// Skip comment introducer and check for hidden command.
sc.Forward(2);
if (sc.ch == '!')
@@ -247,7 +250,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
// Special MySQL single line comment.
sc.SetState(SCE_MYSQL_COMMENTLINE);
sc.Forward(2);
-
+
// Check the third character too. It must be a space or EOL.
if (sc.ch != ' ' && sc.ch != '\n' && sc.ch != '\r')
sc.ChangeState(SCE_MYSQL_OPERATOR);
@@ -258,7 +261,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
}
}
}
-
+
// Do a final check for keywords if we currently have an identifier, to highlight them
// also at the end of a line.
if (sc.state == SCE_MYSQL_IDENTIFIER)
@@ -270,7 +273,7 @@ static void ColouriseMySQLDoc(unsigned int startPos, int length, int initStyle,
if (sc.state == SCE_MYSQL_FUNCTION && sc.ch != '(')
sc.ChangeState(SCE_MYSQL_DEFAULT);
}
-
+
sc.Complete();
}
@@ -321,9 +324,9 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
- bool endFound = false;
- bool whenFound = false;
- bool elseFound = false;
+ bool endPending = false;
+ bool whenPending = false;
+ bool elseIfPending = false;
char nextChar = styler.SafeGetCharAt(startPos);
for (unsigned int i = startPos; length > 0; i++, length--)
@@ -374,18 +377,42 @@ 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
+ // before opening a new one.
+ endPending = false;
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
if (style != stylePrev)
levelNext++;
else
if (style != styleNext)
+ {
levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
break;
case SCE_MYSQL_OPERATOR:
+ if (endPending)
+ {
+ endPending = false;
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
if (currentChar == '(')
levelNext++;
else
if (currentChar == ')')
+ {
levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
+ }
break;
case SCE_MYSQL_MAJORKEYWORD:
case SCE_MYSQL_KEYWORD:
@@ -394,110 +421,98 @@ static void FoldMySQLDoc(unsigned int startPos, int length, int initStyle, WordL
// Reserved and other keywords.
if (style != stylePrev)
{
- bool beginFound = MatchIgnoreCase(styler, i, "begin");
- bool ifFound = MatchIgnoreCase(styler, i, "if");
- bool thenFound = MatchIgnoreCase(styler, i, "then");
- bool whileFound = MatchIgnoreCase(styler, i, "while");
- bool loopFound = MatchIgnoreCase(styler, i, "loop");
- bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
-
- if (!foldOnlyBegin && endFound && (ifFound || whileFound || loopFound))
+ // END decreases the folding level, regardless which keyword follows.
+ bool endFound = MatchIgnoreCase(styler, i, "end");
+ if (endPending)
{
- endFound = false;
levelNext--;
if (levelNext < SC_FOLDLEVELBASE)
levelNext = SC_FOLDLEVELBASE;
-
- // Note that "else" is special here. It may or may not be followed by an "if .. then",
- // but in any case the level stays the same. When followed by an "if .. then" the level
- // will be increased later, if not, then at eol.
}
else
- if (!foldOnlyBegin && MatchIgnoreCase(styler, i, "else"))
+ if (!endFound)
{
- levelNext--;
- elseFound = true;
- }
- else
- if (!foldOnlyBegin && thenFound)
- {
- if (whenFound)
- whenFound = false;
- else
- levelNext++;
- }
+ if (MatchIgnoreCase(styler, i, "begin"))
+ levelNext++;
else
- if (ifFound)
- elseFound = false;
- else
- if (MatchIgnoreCase(styler, i, "when"))
- whenFound = true;
+ {
+ if (!foldOnlyBegin)
+ {
+ bool whileFound = MatchIgnoreCase(styler, i, "while");
+ bool loopFound = MatchIgnoreCase(styler, i, "loop");
+ bool repeatFound = MatchIgnoreCase(styler, i, "repeat");
+ bool caseFound = MatchIgnoreCase(styler, i, "case");
+
+ if (whileFound || loopFound || repeatFound || caseFound)
+ levelNext++;
else
{
- if (beginFound)
- levelNext++;
- else
- if (!foldOnlyBegin && (loopFound || repeatFound || whileFound))
+ // IF alone does not increase the fold level as it is also used in non-block'ed
+ // code like DROP PROCEDURE blah IF EXISTS.
+ // Instead THEN opens the new level (if not part of an ELSEIF or WHEN (case) branch).
+ if (MatchIgnoreCase(styler, i, "then"))
+ {
+ if (!elseIfPending && !whenPending)
+ levelNext++;
+ else
{
- if (endFound)
- endFound = false;
- else
- levelNext++;
+ elseIfPending = false;
+ whenPending = false;
}
- else
- if (MatchIgnoreCase(styler, i, "end"))
- {
- // Multiple "end" in a row are counted multiple times!
- if (endFound)
- {
- levelNext--;
- if (levelNext < SC_FOLDLEVELBASE)
- levelNext = SC_FOLDLEVELBASE;
- }
- endFound = true;
- whenFound = false;
- }
+ }
+ else
+ {
+ // Neither of if/then/while/loop/repeat/case, so check for
+ // sub parts of IF and CASE.
+ if (MatchIgnoreCase(styler, i, "elseif"))
+ elseIfPending = true;
+ if (MatchIgnoreCase(styler, i, "when"))
+ whenPending = true;
+ }
}
+ }
+ }
+ }
+
+ // Keep the current end state for the next round.
+ endPending = endFound;
+ }
+ break;
+
+ default:
+ if (!isspace(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.
+ levelNext--;
+ if (levelNext < SC_FOLDLEVELBASE)
+ levelNext = SC_FOLDLEVELBASE;
}
break;
}
- // Handle the case of a trailing end without an if / while etc, as in the case of a begin.
- if (endFound)
- {
- endFound = false;
- levelNext--;
- if (levelNext < SC_FOLDLEVELBASE)
- levelNext = SC_FOLDLEVELBASE;
- }
-
- if (atEOL)
+ if (atEOL)
{
- if (elseFound)
- {
- levelNext++;
- elseFound = false;
- }
-
- int levelUse = levelCurrent;
- int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
- lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext)
- lev |= SC_FOLDLEVELHEADERFLAG;
- if (lev != styler.LevelAt(lineCurrent))
- styler.SetLevel(lineCurrent, lev);
+ // Apply the new folding level to this line.
+ // Leave pending states as they are otherwise a line break will de-sync
+ // code folding and valid syntax.
+ int levelUse = levelCurrent;
+ int lev = levelUse | levelNext << 16;
+ if (visibleChars == 0 && foldCompact)
+ lev |= SC_FOLDLEVELWHITEFLAG;
+ if (levelUse < levelNext)
+ lev |= SC_FOLDLEVELHEADERFLAG;
+ if (lev != styler.LevelAt(lineCurrent))
+ styler.SetLevel(lineCurrent, lev);
- lineCurrent++;
- levelCurrent = levelNext;
- visibleChars = 0;
- endFound = false;
- whenFound = false;
- }
-
+ lineCurrent++;
+ levelCurrent = levelNext;
+ visibleChars = 0;
+ }
+
if (!isspacechar(currentChar))
- visibleChars++;
- }
+ visibleChars++;
+ }
}
//--------------------------------------------------------------------------------------------------
diff --git a/plugins/scintilla/scintilla/LexNimrod.cxx b/plugins/scintilla/scintilla/LexNimrod.cxx
index 8c4d043..08b76fe 100644
--- a/plugins/scintilla/scintilla/LexNimrod.cxx
+++ b/plugins/scintilla/scintilla/LexNimrod.cxx
@@ -9,18 +9,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -113,7 +116,7 @@ static int scanNumber(Accessor &styler, int pos) {
if (ch == '_' || (ch >= '0' && ch <= '1')) ++pos;
else break;
}
- } else if (ch == '0' &&
+ } else if (ch == '0' &&
(ch2 == 'o' || ch2 == 'O' || ch2 == 'c' || ch2 == 'C')) {
/* octal number: */
pos += 2;
@@ -203,7 +206,7 @@ static void ColouriseNimrodDoc(unsigned int startPos, int length, int initStyle,
case '#': {
bool doccomment = (styler.SafeGetCharAt(pos+1) == '#');
while (pos < max && !isNewLine(styler.SafeGetCharAt(pos, LF))) pos++;
- if (doccomment)
+ if (doccomment)
styler.ColourTo(pos, SCE_C_COMMENTLINEDOC);
else
styler.ColourTo(pos, SCE_P_COMMENTLINE);
@@ -280,7 +283,7 @@ static bool IsQuoteLine(int line, Accessor &styler) {
}
-static void FoldNimrodDoc(unsigned int startPos, int length,
+static void FoldNimrodDoc(unsigned int startPos, int length,
int /*initStyle - unused*/,
WordList *[], Accessor &styler) {
const int maxPos = startPos + length;
@@ -311,7 +314,7 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
int prev_state = SCE_P_DEFAULT & 31;
if (lineCurrent >= 1)
prev_state = styler.StyleAt(startPos - 1) & 31;
- int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) ||
+ int prevQuote = foldQuotes && ((prev_state == SCE_P_TRIPLE) ||
(prev_state == SCE_P_TRIPLEDOUBLE));
int prevComment = 0;
if (lineCurrent >= 1)
@@ -320,7 +323,7 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
// Process all characters to end of requested range or end of any triple quote
// or comment that hangs over the end of the range. Cap processing in all cases
// to end of document (in case of unclosed quote or comment at end).
- while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) ||
+ while ((lineCurrent <= docLines) && ((lineCurrent <= maxLines) ||
prevQuote || prevComment)) {
// Gather info
@@ -338,7 +341,7 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
const int quote_continue = (quote && prevQuote);
const int comment = foldComment && IsCommentLine(lineCurrent, styler);
const int comment_start = (comment && !prevComment && (lineNext <= docLines) &&
- IsCommentLine(lineNext, styler) &&
+ IsCommentLine(lineNext, styler) &&
(lev > SC_FOLDLEVELBASE));
const int comment_continue = (comment && prevComment);
if ((!quote || !prevQuote) && !comment)
@@ -377,8 +380,8 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
}
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
- const int levelBeforeComments =
- Platform::Maximum(indentCurrentLevel,levelAfterComments);
+ const int levelBeforeComments =
+ Maximum(indentCurrentLevel,levelAfterComments);
// Now set all the indent levels on the lines we skipped
// Do this from end to start. Once we encounter one line
@@ -401,7 +404,7 @@ static void FoldNimrodDoc(unsigned int startPos, int length,
// Set fold header on non-quote/non-comment line
if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
- if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) <
+ if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) <
(indentNext & SC_FOLDLEVELNUMBERMASK))
lev |= SC_FOLDLEVELHEADERFLAG;
}
diff --git a/plugins/scintilla/scintilla/LexNsis.cxx b/plugins/scintilla/scintilla/LexNsis.cxx
index 43ddc47..cd74d54 100644
--- a/plugins/scintilla/scintilla/LexNsis.cxx
+++ b/plugins/scintilla/scintilla/LexNsis.cxx
@@ -5,21 +5,25 @@
// Copyright 2003 - 2005 by Angelo Mandato <angelo [at] spaceblue [dot] com>
// Last Updated: 03/13/2005
// The License.txt file describes the conditions under which this software may be distributed.
+
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "CharClassify.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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
diff --git a/plugins/scintilla/scintilla/LexOpal.cxx b/plugins/scintilla/scintilla/LexOpal.cxx
index 221f955..320fe9b 100644
--- a/plugins/scintilla/scintilla/LexOpal.cxx
+++ b/plugins/scintilla/scintilla/LexOpal.cxx
@@ -6,18 +6,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
@@ -92,7 +95,7 @@ inline bool HandleString( unsigned int & cur, unsigned int one_too_much, Accesso
inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
{
char ch;
-
+
if( could_fail )
{
cur++;
@@ -101,7 +104,7 @@ inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, A
styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
return false; // STOP
}
-
+
ch = styler.SafeGetCharAt( cur );
if( ch != '*' )
{
@@ -110,7 +113,7 @@ inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, A
return true;
}
}
-
+
// Wait for comment close
cur++;
bool star_found = false;
@@ -121,7 +124,7 @@ inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, A
styler.ColourTo( cur - 1, SCE_OPAL_COMMENT_BLOCK );
return false; // STOP
}
-
+
ch = styler.SafeGetCharAt( cur );
if( star_found )
{
@@ -155,7 +158,7 @@ inline bool HandleCommentBlock( unsigned int & cur, unsigned int one_too_much, A
inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Accessor & styler, bool could_fail )
{
char ch;
-
+
if( could_fail )
{
cur++;
@@ -164,7 +167,7 @@ inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Ac
styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
return false; // STOP
}
-
+
ch = styler.SafeGetCharAt( cur );
if( ch != '-' )
{
@@ -179,7 +182,7 @@ inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Ac
styler.ColourTo( cur - 1, SCE_OPAL_DEFAULT );
return false; // STOP
}
-
+
ch = styler.SafeGetCharAt( cur );
if( ( ch != ' ' ) && ( ch != '\t' ) )
{
@@ -224,7 +227,7 @@ inline bool HandleCommentLine( unsigned int & cur, unsigned int one_too_much, Ac
{
if( ch == '\015' )
{
- fifteen_found = true;
+ fifteen_found = true;
}
else if( ch == '\012' )
{
@@ -259,7 +262,7 @@ inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor
styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
return false;
}
-
+
ch = styler.SafeGetCharAt( cur );
switch( ch )
{
@@ -269,7 +272,7 @@ inline bool HandleSpace( unsigned int & cur, unsigned int one_too_much, Accessor
case '\012':
cur++;
break;
-
+
default:
styler.ColourTo( cur - 1, SCE_OPAL_SPACE );
styler.StartSegment( cur );
@@ -292,7 +295,7 @@ inline bool HandleInteger( unsigned int & cur, unsigned int one_too_much, Access
}
ch = styler.SafeGetCharAt( cur );
- if( !isdigit( ch ) )
+ if( !( isascii( ch ) && isdigit( ch ) ) )
{
styler.ColourTo( cur - 1, SCE_OPAL_INTEGER );
styler.StartSegment( cur );
@@ -311,10 +314,10 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
{
ch = styler.SafeGetCharAt( cur );
if( ( ch != '_' ) && ( ch != '-' ) &&
- !islower( ch ) && !isupper( ch ) && !isdigit( ch ) ) break;
+ !( isascii( ch ) && ( islower( ch ) || isupper( ch ) || isdigit( ch ) ) ) ) break;
cur++;
- if( cur >= one_too_much )
+ if( cur >= one_too_much )
{
break;
}
@@ -323,7 +326,7 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
const int ide_len = cur - beg + 1;
char * ide = new char[ ide_len ];
getRange( beg, cur, styler, ide, ide_len );
-
+
WordList & keywords = *keywordlists[ 0 ];
WordList & classwords = *keywordlists[ 1 ];
@@ -338,8 +341,8 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
}
else
{
- styler.StartSegment( cur );
- return true;
+ styler.StartSegment( cur );
+ return true;
}
}
else if( classwords.InList( ide ) ) // Sort
@@ -353,8 +356,8 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
}
else
{
- styler.StartSegment( cur );
- return true;
+ styler.StartSegment( cur );
+ return true;
}
}
else if( !strcmp( ide, "true" ) || !strcmp( ide, "false" ) ) // Bool const
@@ -368,8 +371,8 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
}
else
{
- styler.StartSegment( cur );
- return true;
+ styler.StartSegment( cur );
+ return true;
}
}
else // Unknown keyword
@@ -384,7 +387,7 @@ inline bool HandleWord( unsigned int & cur, unsigned int one_too_much, Accessor
else
{
styler.StartSegment( cur );
- return true;
+ return true;
}
}
@@ -400,7 +403,7 @@ inline bool HandleSkip( unsigned int & cur, unsigned int one_too_much, Accessor
}
else
{
- styler.StartSegment( cur );
+ styler.StartSegment( cur );
return true;
}
}
@@ -444,11 +447,11 @@ static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle,
if( !HandleString( cur, one_too_much, styler ) ) return;
state = SCE_OPAL_DEFAULT;
break;
-
+
default: // SCE_OPAL_DEFAULT:
{
char ch = styler.SafeGetCharAt( cur );
-
+
switch( ch )
{
// String
@@ -483,20 +486,20 @@ static void ColouriseOpalDoc( unsigned int startPos, int length, int initStyle,
case '\012':
if( !HandleSpace( cur, one_too_much, styler ) ) return;
break;
-
+
default:
{
// Integer
- if( isdigit( ch ) )
+ if( isascii( ch ) && isdigit( ch ) )
{
if( !HandleInteger( cur, one_too_much, styler ) ) return;
}
// Keyword
- else if( islower( ch ) || isupper( ch ) )
+ else if( isascii( ch ) && ( islower( ch ) || isupper( ch ) ) )
{
if( !HandleWord( cur, one_too_much, styler, keywordlists ) ) return;
-
+
}
// Skip
diff --git a/plugins/scintilla/scintilla/LexOthers.cxx b/plugins/scintilla/scintilla/LexOthers.cxx
index 75458f6..bc2c287 100644
--- a/plugins/scintilla/scintilla/LexOthers.cxx
+++ b/plugins/scintilla/scintilla/LexOthers.cxx
@@ -8,19 +8,22 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "CharClassify.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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
@@ -37,6 +40,10 @@ static bool Is1To9(char ch) {
return (ch >= '1') && (ch <= '9');
}
+static bool IsAlphabetic(int ch) {
+ return isascii(ch) && isalpha(ch);
+}
+
static inline bool AtEOL(Accessor &styler, unsigned int i) {
return (styler[i] == '\n') ||
((styler[i] == '\r') && (styler.SafeGetCharAt(i + 1) != '\n'));
@@ -51,7 +58,7 @@ static bool IsBOperator(char ch) {
// Tests for BATCH Separators
static bool IsBSeparator(char ch) {
return (ch == '\\') || (ch == '.') || (ch == ';') ||
- (ch == '\"') || (ch == '\'') || (ch == '/') || (ch == ')');
+ (ch == '\"') || (ch == '\'') || (ch == '/');
}
static void ColouriseBatchLine(
@@ -101,7 +108,7 @@ static void ColouriseBatchLine(
}
return;
// Check for Drive Change (Drive Change is internal command) - return if found
- } else if ((isalpha(lineBuffer[offset])) &&
+ } else if ((IsAlphabetic(lineBuffer[offset])) &&
(lineBuffer[offset + 1] == ':') &&
((isspacechar(lineBuffer[offset + 2])) ||
(((lineBuffer[offset + 2] == '\\')) &&
@@ -502,7 +509,7 @@ static void ColouriseDiffLine(char *lineBuffer, int endLine, Accessor &styler) {
styler.ColourTo(endLine, SCE_DIFF_COMMAND);
} else if (0 == strncmp(lineBuffer, "Index: ", 7)) { // For subversion's diff
styler.ColourTo(endLine, SCE_DIFF_COMMAND);
- } else if (0 == strncmp(lineBuffer, "---", 3)) {
+ } else if (0 == strncmp(lineBuffer, "---", 3) && lineBuffer[3] != '-') {
// In a context diff, --- appears in both the header and the position markers
if (lineBuffer[3] == ' ' && atoi(lineBuffer + 4) && !strchr(lineBuffer, '/'))
styler.ColourTo(endLine, SCE_DIFF_POSITION);
@@ -723,10 +730,10 @@ static void ColourisePropsDoc(unsigned int startPos, int length, int, WordList *
unsigned int linePos = 0;
unsigned int startLine = startPos;
- // property lexer.props.allow.initial.spaces
- // For properties files, set to 0 to style all lines that start with whitespace in the default style.
- // This is not suitable for SciTE .properties files which use indentation for flow control but
- // can be used for RFC2822 text where indentation is used for continuation lines.
+ // property lexer.props.allow.initial.spaces
+ // For properties files, set to 0 to style all lines that start with whitespace in the default style.
+ // This is not suitable for SciTE .properties files which use indentation for flow control but
+ // can be used for RFC2822 text where indentation is used for continuation lines.
bool allowInitialSpaces = styler.GetPropertyInt("lexer.props.allow.initial.spaces", 1) != 0;
for (unsigned int i = startPos; i < startPos + length; i++) {
@@ -847,13 +854,17 @@ static void ColouriseMakeLine(
styler.ColourTo(endPos, SCE_MAKE_PREPROCESSOR);
return;
}
+ int varCount = 0;
while (i < lengthLine) {
if (lineBuffer[i] == '$' && lineBuffer[i + 1] == '(') {
styler.ColourTo(startLine + i - 1, state);
state = SCE_MAKE_IDENTIFIER;
+ varCount++;
} else if (state == SCE_MAKE_IDENTIFIER && lineBuffer[i] == ')') {
- styler.ColourTo(startLine + i, state);
- state = SCE_MAKE_DEFAULT;
+ if (--varCount == 0) {
+ styler.ColourTo(startLine + i, state);
+ state = SCE_MAKE_DEFAULT;
+ }
}
// skip identifier and target styling if this is a command line
@@ -922,8 +933,8 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
// Command or return status
return SCE_ERR_CMD;
} else if (lineBuffer[0] == '<') {
- // Diff removal, but not interested. Trapped to avoid hitting CTAG cases.
- return SCE_ERR_DEFAULT;
+ // Diff removal.
+ return SCE_ERR_DIFF_DELETION;
} else if (lineBuffer[0] == '!') {
return SCE_ERR_DIFF_CHANGED;
} else if (lineBuffer[0] == '+') {
@@ -961,17 +972,17 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
} else if (strstart(lineBuffer, "Warning ")) {
// Borland warning message
return SCE_ERR_BORLAND;
- } else if (strstr(lineBuffer, "at line " ) &&
- (strstr(lineBuffer, "at line " ) < (lineBuffer + lengthLine)) &&
+ } else if (strstr(lineBuffer, "at line ") &&
+ (strstr(lineBuffer, "at line ") < (lineBuffer + lengthLine)) &&
strstr(lineBuffer, "file ") &&
(strstr(lineBuffer, "file ") < (lineBuffer + lengthLine))) {
// Lua 4 error message
return SCE_ERR_LUA;
- } else if (strstr(lineBuffer, " at " ) &&
- (strstr(lineBuffer, " at " ) < (lineBuffer + lengthLine)) &&
+ } else if (strstr(lineBuffer, " at ") &&
+ (strstr(lineBuffer, " at ") < (lineBuffer + lengthLine)) &&
strstr(lineBuffer, " line ") &&
(strstr(lineBuffer, " line ") < (lineBuffer + lengthLine)) &&
- (strstr(lineBuffer, " at " ) < (strstr(lineBuffer, " line ")))) {
+ (strstr(lineBuffer, " at ") < (strstr(lineBuffer, " line ")))) {
// perl error message
return SCE_ERR_PERL;
} else if ((memcmp(lineBuffer, " at ", 6) == 0) &&
@@ -1065,7 +1076,7 @@ static int RecogniseErrorListLine(const char *lineBuffer, unsigned int lengthLin
numstep = 1; // ch was ' ', handle as if it's a delphi errorline, only add 1 to i.
else
numstep = 2; // otherwise add 2.
- for (j = i + numstep; j < lengthLine && isalpha(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
+ for (j = i + numstep; j < lengthLine && IsAlphabetic(lineBuffer[j]) && chPos < sizeof(word) - 1; j++)
word[chPos++] = lineBuffer[j];
word[chPos] = 0;
if (!CompareCaseInsensitive(word, "error") || !CompareCaseInsensitive(word, "warning") ||
@@ -1131,11 +1142,11 @@ static void ColouriseErrorListDoc(unsigned int startPos, int length, int, WordLi
styler.StartSegment(startPos);
unsigned int linePos = 0;
- // property lexer.errorlist.value.separate
- // For lines in the output pane that are matches from Find in Files or GCC-style
- // diagnostics, style the path and line number separately from the rest of the
- // line with style 21 used for the rest of the line.
- // This allows matched text to be more easily distinguished from its location.
+ // property lexer.errorlist.value.separate
+ // For lines in the output pane that are matches from Find in Files or GCC-style
+ // diagnostics, style the path and line number separately from the rest of the
+ // line with style 21 used for the rest of the line.
+ // This allows matched text to be more easily distinguished from its location.
bool valueSeparate = styler.GetPropertyInt("lexer.errorlist.value.separate", 0) != 0;
for (unsigned int i = startPos; i < startPos + length; i++) {
lineBuffer[linePos++] = styler[i];
@@ -1162,7 +1173,7 @@ static int isTag(int start, Accessor &styler) {
while (i < 5 && e) {
s[i] = styler[start + i];
i++;
- e = styler[start + i] != '{';
+ e = (strchr("{ \t", styler[start + i]) == NULL);
}
s[i] = '\0';
return (strcmp(s, "begin") == 0) || (strcmp(s, "end") == 0);
@@ -1252,13 +1263,13 @@ static void ColouriseLatexDoc(unsigned int startPos, int length, int initStyle,
styler.ColourTo(lengthDoc-1, state);
}
-static const char * const batchWordListDesc[] = {
+static const char *const batchWordListDesc[] = {
"Internal Commands",
"External Commands",
0
};
-static const char * const emptyWordListDesc[] = {
+static const char *const emptyWordListDesc[] = {
0
};
diff --git a/plugins/scintilla/scintilla/LexPB.cxx b/plugins/scintilla/scintilla/LexPB.cxx
index abc0ddc..a7b5690 100644
--- a/plugins/scintilla/scintilla/LexPB.cxx
+++ b/plugins/scintilla/scintilla/LexPB.cxx
@@ -35,18 +35,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexPLM.cxx b/plugins/scintilla/scintilla/LexPLM.cxx
index 604850f..747d158 100644
--- a/plugins/scintilla/scintilla/LexPLM.cxx
+++ b/plugins/scintilla/scintilla/LexPLM.cxx
@@ -4,18 +4,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
diff --git a/plugins/scintilla/scintilla/LexPOV.cxx b/plugins/scintilla/scintilla/LexPOV.cxx
index b845b2d..353fbbe 100644
--- a/plugins/scintilla/scintilla/LexPOV.cxx
+++ b/plugins/scintilla/scintilla/LexPOV.cxx
@@ -16,18 +16,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexPS.cxx b/plugins/scintilla/scintilla/LexPS.cxx
index 2edcff1..3661c4b 100644
--- a/plugins/scintilla/scintilla/LexPS.cxx
+++ b/plugins/scintilla/scintilla/LexPS.cxx
@@ -8,18 +8,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexPascal.cxx b/plugins/scintilla/scintilla/LexPascal.cxx
index 3dcf35a..867b00e 100644
--- a/plugins/scintilla/scintilla/LexPascal.cxx
+++ b/plugins/scintilla/scintilla/LexPascal.cxx
@@ -11,20 +11,20 @@
A few words about features of the new completely rewritten LexPascal...
-Generally speaking LexPascal tries to support all available Delphi features (up
+Generally speaking LexPascal tries to support all available Delphi features (up
to Delphi 2009 at this time), including .NET specific features.
~ HIGHLIGHTING:
-If you enable "lexer.pascal.smart.highlighting" property, some keywords will
-only be highlighted in appropriate context. As implemented those are keywords
-related to property and DLL exports declarations (similar to how Delphi IDE
-works).
+If you enable "lexer.pascal.smart.highlighting" property, some keywords will
+only be highlighted in appropriate context. As implemented those are keywords
+related to property and DLL exports declarations (similar to how Delphi IDE
+works).
-For example, keywords "read" and "write" will only be highlighted if they are in
+For example, keywords "read" and "write" will only be highlighted if they are in
property declaration:
-property MyProperty: boolean read FMyProperty write FMyProperty;
+property MyProperty: boolean read FMyProperty write FMyProperty;
~ FOLDING:
@@ -32,34 +32,34 @@ Folding is supported in the following cases:
- Folding of stream-like comments
- Folding of groups of consecutive line comments
-- Folding of preprocessor blocks (the following preprocessor blocks are
-supported: IF / IFEND; IFDEF, IFNDEF, IFOPT / ENDIF and REGION / ENDREGION
+- Folding of preprocessor blocks (the following preprocessor blocks are
+supported: IF / IFEND; IFDEF, IFNDEF, IFOPT / ENDIF and REGION / ENDREGION
blocks), including nesting of preprocessor blocks up to 255 levels
-- Folding of code blocks on appropriate keywords (the following code blocks are
-supported: "begin, asm, record, try, case / end" blocks, class & object
+- Folding of code blocks on appropriate keywords (the following code blocks are
+supported: "begin, asm, record, try, case / end" blocks, class & object
declarations and interface declarations)
Remarks:
-- Folding of code blocks tries to handle all special cases in which folding
+- Folding of code blocks tries to handle all special cases in which folding
should not occur. As implemented those are:
-1. Structure "record case / end" (there's only one "end" statement and "case" is
+1. Structure "record case / end" (there's only one "end" statement and "case" is
ignored as fold point)
-2. Forward class declarations ("type TMyClass = class;") and object method
-declarations ("TNotifyEvent = procedure(Sender: TObject) of object;") are
+2. Forward class declarations ("type TMyClass = class;") and object method
+declarations ("TNotifyEvent = procedure(Sender: TObject) of object;") are
ignored as fold points
-3. Simplified complete class declarations ("type TMyClass = class(TObject);")
+3. Simplified complete class declarations ("type TMyClass = class(TObject);")
are ignored as fold points
-4. Every other situation when class keyword doesn't actually start class
-declaration ("class procedure", "class function", "class of", "class var",
+4. Every other situation when class keyword doesn't actually start class
+declaration ("class procedure", "class function", "class of", "class var",
"class property" and "class operator")
-- Folding of code blocks inside preprocessor blocks is disabled (any comments
-inside them will be folded fine) because there is no guarantee that complete
-code block will be contained inside folded preprocessor block in which case
-folded code block could end prematurely at the end of preprocessor block if
-there is no closing statement inside. This was done in order to properly process
+- Folding of code blocks inside preprocessor blocks is disabled (any comments
+inside them will be folded fine) because there is no guarantee that complete
+code block will be contained inside folded preprocessor block in which case
+folded code block could end prematurely at the end of preprocessor block if
+there is no closing statement inside. This was done in order to properly process
document that may contain something like this:
type
@@ -76,52 +76,54 @@ type
...
end;
-If class declarations were folded, then the second class declaration would end
-at "$ENDIF" statement, first class statement would end at "end;" statement and
-preprocessor "$IFDEF" block would go all the way to the end of document.
-However, having in mind all this, if you want to enable folding of code blocks
-inside preprocessor blocks, you can disable folding of preprocessor blocks by
-changing "fold.preprocessor" property, in which case everything inside them
+If class declarations were folded, then the second class declaration would end
+at "$ENDIF" statement, first class statement would end at "end;" statement and
+preprocessor "$IFDEF" block would go all the way to the end of document.
+However, having in mind all this, if you want to enable folding of code blocks
+inside preprocessor blocks, you can disable folding of preprocessor blocks by
+changing "fold.preprocessor" property, in which case everything inside them
would be folded.
~ KEYWORDS:
-The list of keywords that can be used in pascal.properties file (up to Delphi
+The list of keywords that can be used in pascal.properties file (up to Delphi
2009):
-- Keywords: absolute abstract and array as asm assembler automated begin case
-cdecl class const constructor deprecated destructor dispid dispinterface div do
-downto dynamic else end except export exports external far file final
-finalization finally for forward function goto if implementation in inherited
-initialization inline interface is label library message mod near nil not object
-of on or out overload override packed pascal platform private procedure program
-property protected public published raise record register reintroduce repeat
-resourcestring safecall sealed set shl shr static stdcall strict string then
+- Keywords: absolute abstract and array as asm assembler automated begin case
+cdecl class const constructor deprecated destructor dispid dispinterface div do
+downto dynamic else end except export exports external far file final
+finalization finally for forward function goto if implementation in inherited
+initialization inline interface is label library message mod near nil not object
+of on or out overload override packed pascal platform private procedure program
+property protected public published raise record register reintroduce repeat
+resourcestring safecall sealed set shl shr static stdcall strict string then
threadvar to try type unit unsafe until uses var varargs virtual while with xor
-- Keywords related to the "smart highlithing" feature: add default implements
+- Keywords related to the "smart highlithing" feature: add default implements
index name nodefault read readonly remove stored write writeonly
-- Keywords related to Delphi packages (in addition to all above): package
+- Keywords related to Delphi packages (in addition to all above): package
contains requires
*/
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
@@ -155,12 +157,12 @@ static void GetForwardRangeLowered(unsigned int start,
}
enum {
- stateInAsm = 0x1000,
- stateInProperty = 0x2000,
- stateInExport = 0x4000,
- stateFoldInPreprocessor = 0x0100,
- stateFoldInRecord = 0x0200,
- stateFoldInPreprocessorLevelMask = 0x00FF,
+ stateInAsm = 0x1000,
+ stateInProperty = 0x2000,
+ stateInExport = 0x4000,
+ stateFoldInPreprocessor = 0x0100,
+ stateFoldInRecord = 0x0200,
+ stateFoldInPreprocessorLevelMask = 0x00FF,
stateFoldMaskAll = 0x0FFF
};
@@ -190,11 +192,11 @@ static void ClassifyPascalWord(WordList *keywordlists[], StyleContext &sc, int &
ignoreKeyword = true;
} else if (!(curLineState & stateInExport) && strcmp(s, "name") == 0) {
ignoreKeyword = true;
- } else if (!(curLineState & stateInProperty) &&
- (strcmp(s, "read") == 0 || strcmp(s, "write") == 0 ||
- strcmp(s, "default") == 0 || strcmp(s, "nodefault") == 0 ||
- strcmp(s, "stored") == 0 || strcmp(s, "implements") == 0 ||
- strcmp(s, "readonly") == 0 || strcmp(s, "writeonly") == 0 ||
+ } else if (!(curLineState & stateInProperty) &&
+ (strcmp(s, "read") == 0 || strcmp(s, "write") == 0 ||
+ strcmp(s, "default") == 0 || strcmp(s, "nodefault") == 0 ||
+ strcmp(s, "stored") == 0 || strcmp(s, "implements") == 0 ||
+ strcmp(s, "readonly") == 0 || strcmp(s, "writeonly") == 0 ||
strcmp(s, "add") == 0 || strcmp(s, "remove") == 0)) {
ignoreKeyword = true;
}
@@ -367,7 +369,7 @@ static void SetFoldInPreprocessorLevelFlag(int &lineFoldStateCurrent, unsigned i
lineFoldStateCurrent |= nestLevel & stateFoldInPreprocessorLevelMask;
}
-static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
+static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
unsigned int startPos, Accessor &styler) {
CharacterSet setWord(CharacterSet::setAlpha);
@@ -376,17 +378,17 @@ static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFold
unsigned int nestLevel = GetFoldInPreprocessorLevelFlag(lineFoldStateCurrent);
- if (strcmp(s, "if") == 0 ||
- strcmp(s, "ifdef") == 0 ||
- strcmp(s, "ifndef") == 0 ||
- strcmp(s, "ifopt") == 0 ||
+ if (strcmp(s, "if") == 0 ||
+ strcmp(s, "ifdef") == 0 ||
+ strcmp(s, "ifndef") == 0 ||
+ strcmp(s, "ifopt") == 0 ||
strcmp(s, "region") == 0) {
nestLevel++;
SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
lineFoldStateCurrent |= stateFoldInPreprocessor;
levelCurrent++;
- } else if (strcmp(s, "endif") == 0 ||
- strcmp(s, "ifend") == 0 ||
+ } else if (strcmp(s, "endif") == 0 ||
+ strcmp(s, "ifend") == 0 ||
strcmp(s, "endregion") == 0) {
nestLevel--;
SetFoldInPreprocessorLevelFlag(lineFoldStateCurrent, nestLevel);
@@ -400,12 +402,12 @@ static void ClassifyPascalPreprocessorFoldPoint(int &levelCurrent, int &lineFold
}
}
-static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos,
+static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos,
Accessor &styler, bool includeChars = false) {
CharacterSet setWord(CharacterSet::setAlphaNum, "_");
unsigned int j = currentPos + 1;
char ch = styler.SafeGetCharAt(j);
- while ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
+ while ((j < endPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
IsStreamCommentStyle(styler.StyleAt(j)) || (includeChars && setWord.Contains(ch)))) {
j++;
ch = styler.SafeGetCharAt(j);
@@ -413,8 +415,8 @@ static unsigned int SkipWhiteSpace(unsigned int currentPos, unsigned int endPos,
return j;
}
-static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
- int startPos, unsigned int endPos,
+static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCurrent,
+ int startPos, unsigned int endPos,
unsigned int lastStart, unsigned int currentPos, Accessor &styler) {
char s[100];
GetRangeLowered(lastStart, currentPos, styler, s, sizeof(s));
@@ -422,9 +424,9 @@ static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCur
if (strcmp(s, "record") == 0) {
lineFoldStateCurrent |= stateFoldInRecord;
levelCurrent++;
- } else if (strcmp(s, "begin") == 0 ||
- strcmp(s, "asm") == 0 ||
- strcmp(s, "try") == 0 ||
+ } else if (strcmp(s, "begin") == 0 ||
+ strcmp(s, "asm") == 0 ||
+ strcmp(s, "try") == 0 ||
(strcmp(s, "case") == 0 && !(lineFoldStateCurrent & stateFoldInRecord))) {
levelCurrent++;
} else if (strcmp(s, "class") == 0 || strcmp(s, "object") == 0) {
@@ -436,13 +438,13 @@ static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCur
CharacterSet setWord(CharacterSet::setAlphaNum, "_");
if (styler.SafeGetCharAt(j) == ';') {
- // Handle forward class declarations ("type TMyClass = class;")
+ // Handle forward class declarations ("type TMyClass = class;")
// and object method declarations ("TNotifyEvent = procedure(Sender: TObject) of object;")
ignoreKeyword = true;
} else if (strcmp(s, "class") == 0) {
// "class" keyword has a few more special cases...
if (styler.SafeGetCharAt(j) == '(') {
- // Handle simplified complete class declarations ("type TMyClass = class(TObject);")
+ // Handle simplified complete class declarations ("type TMyClass = class(TObject);")
j = SkipWhiteSpace(j, endPos, styler, true);
if (j < endPos && styler.SafeGetCharAt(j) == ')') {
j = SkipWhiteSpace(j, endPos, styler);
@@ -454,11 +456,11 @@ static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCur
char s2[11]; // Size of the longest possible keyword + one additional character + null
GetForwardRangeLowered(j, setWord, styler, s2, sizeof(s2));
- if (strcmp(s2, "procedure") == 0 ||
- strcmp(s2, "function") == 0 ||
- strcmp(s2, "of") == 0 ||
- strcmp(s2, "var") == 0 ||
- strcmp(s2, "property") == 0 ||
+ if (strcmp(s2, "procedure") == 0 ||
+ strcmp(s2, "function") == 0 ||
+ strcmp(s2, "of") == 0 ||
+ strcmp(s2, "var") == 0 ||
+ strcmp(s2, "property") == 0 ||
strcmp(s2, "operator") == 0) {
ignoreKeyword = true;
}
@@ -473,7 +475,7 @@ static void ClassifyPascalWordFoldPoint(int &levelCurrent, int &lineFoldStateCur
bool ignoreKeyword = true;
int j = lastStart - 1;
char ch = styler.SafeGetCharAt(j);
- while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
+ while ((j >= startPos) && (IsASpaceOrTab(ch) || ch == '\r' || ch == '\n' ||
IsStreamCommentStyle(styler.StyleAt(j)))) {
j--;
ch = styler.SafeGetCharAt(j);
@@ -539,7 +541,7 @@ static void FoldPascalDoc(unsigned int startPos, int length, int initStyle, Word
if (foldPreprocessor) {
if (style == SCE_PAS_PREPROCESSOR && ch == '{' && chNext == '$') {
ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 2, styler);
- } else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*'
+ } else if (style == SCE_PAS_PREPROCESSOR2 && ch == '(' && chNext == '*'
&& styler.SafeGetCharAt(i + 2) == '$') {
ClassifyPascalPreprocessorFoldPoint(levelCurrent, lineFoldStateCurrent, i + 3, styler);
}
diff --git a/plugins/scintilla/scintilla/LexPerl.cxx b/plugins/scintilla/scintilla/LexPerl.cxx
index 0c66036..7f0cbcf 100644
--- a/plugins/scintilla/scintilla/LexPerl.cxx
+++ b/plugins/scintilla/scintilla/LexPerl.cxx
@@ -1,6 +1,7 @@
// Scintilla source code edit control
/** @file LexPerl.cxx
** Lexer for Perl.
+ ** Converted to lexer object by "Udo Lechner" <dlchnr(at)gmx(dot)net>
**/
// Copyright 1998-2008 by Neil Hodgson <neilh scintilla org>
// Lexical analysis fixes by Kein-Hong Man <mkh pl jaring my>
@@ -8,19 +9,28 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include <string>
+#include <map>
+
+#include "ILexer.h"
#include "Scintilla.h"
#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "StyleContext.h"
#include "CharacterSet.h"
+#include "LexerModule.h"
+#include "OptionSet.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -59,8 +69,7 @@ using namespace Scintilla;
#define BACK_OPERATOR 1 // whitespace/comments are insignificant
#define BACK_KEYWORD 2 // operators/keywords are needed for disambiguation
-static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, Accessor &styler)
-{
+static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywords, LexAccessor &styler) {
// old-style keyword matcher; needed because GetCurrent() needs
// current segment to be committed, but we may abandon early...
char s[100];
@@ -71,9 +80,8 @@ static bool isPerlKeyword(unsigned int start, unsigned int end, WordList &keywor
return keywords.InList(s);
}
-static int disambiguateBareword(Accessor &styler, unsigned int bk, unsigned int fw,
- int backFlag, unsigned int backPos, unsigned int endPos)
-{
+static int disambiguateBareword(LexAccessor &styler, unsigned int bk, unsigned int fw,
+ int backFlag, unsigned int backPos, unsigned int endPos) {
// identifiers are recognized by Perl as barewords under some
// conditions, the following attempts to do the disambiguation
// by looking backward and forward; result in 2 LSB
@@ -94,25 +102,25 @@ static int disambiguateBareword(Accessor &styler, unsigned int bk, unsigned int
// {bareword: possible variable spec
brace = true;
} else if ((ch == '&' && styler.SafeGetCharAt(bk - 1) != '&')
- // &bareword: subroutine call
- || styler.Match(bk - 1, "->")
- // ->bareword: part of variable spec
- || styler.Match(bk - 2, "sub")) {
- // sub bareword: subroutine declaration
- // (implied BACK_KEYWORD, no keywords end in 'sub'!)
+ // &bareword: subroutine call
+ || styler.Match(bk - 1, "->")
+ // ->bareword: part of variable spec
+ || styler.Match(bk - 2, "sub")) {
+ // sub bareword: subroutine declaration
+ // (implied BACK_KEYWORD, no keywords end in 'sub'!)
result |= 1;
}
// next, scan forward after word past tab/spaces only;
// if ch isn't one of '[{(,' we can skip the test
if ((ch == '{' || ch == '(' || ch == '['|| ch == ',')
- && fw < endPos) {
+ && fw < endPos) {
while (ch = static_cast<unsigned char>(styler.SafeGetCharAt(fw)),
- IsASpaceOrTab(ch) && fw < endPos) {
+ IsASpaceOrTab(ch) && fw < endPos) {
fw++;
}
if ((ch == '}' && brace)
- // {bareword}: variable spec
- || styler.Match(fw, "=>")) {
+ // {bareword}: variable spec
+ || styler.Match(fw, "=>")) {
// [{(, bareword=>: hash literal
result |= 2;
}
@@ -120,17 +128,15 @@ static int disambiguateBareword(Accessor &styler, unsigned int bk, unsigned int
return result;
}
-static void skipWhitespaceComment(Accessor &styler, unsigned int &p)
-{
+static void skipWhitespaceComment(LexAccessor &styler, unsigned int &p) {
// when backtracking, we need to skip whitespace and comments
int style;
while ((p > 0) && (style = styler.StyleAt(p),
- style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE))
+ style == SCE_PL_DEFAULT || style == SCE_PL_COMMENTLINE))
p--;
}
-static int styleBeforeBracePair(Accessor &styler, unsigned int bk)
-{
+static int styleBeforeBracePair(LexAccessor &styler, unsigned int bk) {
// backtrack to find open '{' corresponding to a '}', balanced
// return significant style to be tested for '/' disambiguation
int braceCount = 1;
@@ -157,8 +163,7 @@ static int styleBeforeBracePair(Accessor &styler, unsigned int bk)
return SCE_PL_DEFAULT;
}
-static int styleCheckIdentifier(Accessor &styler, unsigned int bk)
-{
+static int styleCheckIdentifier(LexAccessor &styler, unsigned int bk) {
// backtrack to classify sub-styles of identifier under test
// return sub-style to be tested for '/' disambiguation
if (styler.SafeGetCharAt(bk) == '>') // inputsymbol, like <foo>
@@ -170,7 +175,7 @@ static int styleCheckIdentifier(Accessor &styler, unsigned int bk)
while (bk > 0) {
int bkstyle = styler.StyleAt(bk);
if (bkstyle == SCE_PL_DEFAULT
- || bkstyle == SCE_PL_COMMENTLINE) {
+ || bkstyle == SCE_PL_COMMENTLINE) {
// skip whitespace, comments
} else if (bkstyle == SCE_PL_OPERATOR) {
// test for "->" and "::"
@@ -183,8 +188,7 @@ static int styleCheckIdentifier(Accessor &styler, unsigned int bk)
return 0;
}
-static int inputsymbolScan(Accessor &styler, unsigned int pos, unsigned int endPos)
-{
+static int inputsymbolScan(LexAccessor &styler, unsigned int pos, unsigned int endPos) {
// looks forward for matching > on same line; a bit ugly
unsigned int fw = pos;
while (++fw < endPos) {
@@ -200,8 +204,7 @@ static int inputsymbolScan(Accessor &styler, unsigned int pos, unsigned int endP
return 0;
}
-static int podLineScan(Accessor &styler, unsigned int &pos, unsigned int endPos)
-{
+static int podLineScan(LexAccessor &styler, unsigned int &pos, unsigned int endPos) {
// forward scan the current line to classify line for POD style
int state = -1;
while (pos <= endPos) {
@@ -225,8 +228,7 @@ static int podLineScan(Accessor &styler, unsigned int &pos, unsigned int endPos)
return state;
}
-static bool styleCheckSubPrototype(Accessor &styler, unsigned int bk)
-{
+static bool styleCheckSubPrototype(LexAccessor &styler, unsigned int bk) {
// backtrack to identify if we're starting a subroutine prototype
// we also need to ignore whitespace/comments:
// 'sub' [whitespace|comment] <identifier> [whitespace|comment]
@@ -239,13 +241,12 @@ static bool styleCheckSubPrototype(Accessor &styler, unsigned int bk)
}
skipWhitespaceComment(styler, bk);
if (bk < 2 || styler.StyleAt(bk) != SCE_PL_WORD // check "sub" keyword
- || !styler.Match(bk - 2, "sub")) // assume suffix is unique!
+ || !styler.Match(bk - 2, "sub")) // assume suffix is unique!
return false;
return true;
}
-static bool isMatch(const char *sref, char *s)
-{
+static bool isMatch(const char *sref, char *s) {
// match per-line delimiter - must kill trailing CR if CRLF
int i = strlen(s);
if (i != 0 && s[i - 1] == '\r')
@@ -270,10 +271,163 @@ static int opposite(int ch) {
return ch;
}
-static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
- WordList *keywordlists[], Accessor &styler) {
+static bool IsCommentLine(int line, LexAccessor &styler) {
+ int pos = styler.LineStart(line);
+ int eol_pos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eol_pos; i++) {
+ char ch = styler[i];
+ int style = styler.StyleAt(i);
+ if (ch == '#' && style == SCE_PL_COMMENTLINE)
+ return true;
+ else if (!IsASpaceOrTab(ch))
+ return false;
+ }
+ return false;
+}
+
+static bool IsPackageLine(int line, LexAccessor &styler) {
+ int pos = styler.LineStart(line);
+ int style = styler.StyleAt(pos);
+ if (style == SCE_PL_WORD && styler.Match(pos, "package")) {
+ return true;
+ }
+ return false;
+}
- WordList &keywords = *keywordlists[0];
+static int PodHeadingLevel(int pos, LexAccessor &styler) {
+ int lvl = static_cast<unsigned char>(styler.SafeGetCharAt(pos + 5));
+ if (lvl >= '1' && lvl <= '4') {
+ return lvl - '0';
+ }
+ return 0;
+}
+
+// An individual named option for use in an OptionSet
+
+// Options used for LexerPerl
+struct OptionsPerl {
+ bool fold;
+ bool foldComment;
+ bool foldCompact;
+ // Custom folding of POD and packages
+ bool foldPOD; // fold.perl.pod
+ // Enable folding Pod blocks when using the Perl lexer.
+ bool foldPackage; // fold.perl.package
+ // Enable folding packages when using the Perl lexer.
+
+ bool foldCommentExplicit;
+
+ bool foldAtElse;
+
+ OptionsPerl() {
+ fold = false;
+ foldComment = false;
+ foldCompact = true;
+ foldPOD = true;
+ foldPackage = true;
+ foldCommentExplicit = true;
+ foldAtElse = false;
+ }
+};
+
+static const char *const perlWordListDesc[] = {
+ "Keywords",
+ 0
+};
+
+struct OptionSetPerl : public OptionSet<OptionsPerl> {
+ OptionSetPerl() {
+ DefineProperty("fold", &OptionsPerl::fold);
+
+ DefineProperty("fold.comment", &OptionsPerl::foldComment);
+
+ DefineProperty("fold.compact", &OptionsPerl::foldCompact);
+
+ DefineProperty("fold.perl.pod", &OptionsPerl::foldPOD,
+ "Set to 0 to disable folding Pod blocks when using the Perl lexer.");
+
+ DefineProperty("fold.perl.package", &OptionsPerl::foldPackage,
+ "Set to 0 to disable folding packages when using the Perl lexer.");
+
+ DefineProperty("fold.perl.comment.explicit", &OptionsPerl::foldCommentExplicit,
+ "Set to 0 to disable explicit folding.");
+
+ DefineProperty("fold.perl.at.else", &OptionsPerl::foldAtElse,
+ "This option enables Perl folding on a \"} else {\" line of an if statement.");
+
+ DefineWordListSets(perlWordListDesc);
+ }
+};
+
+class LexerPerl : public ILexer {
+ WordList keywords;
+ OptionsPerl options;
+ OptionSetPerl osPerl;
+public:
+ LexerPerl() {
+ }
+ ~LexerPerl() {
+ }
+ void SCI_METHOD Release() {
+ delete this;
+ }
+ int SCI_METHOD Version() const {
+ return lvOriginal;
+ }
+ const char *SCI_METHOD PropertyNames() {
+ return osPerl.PropertyNames();
+ }
+ int SCI_METHOD PropertyType(const char *name) {
+ return osPerl.PropertyType(name);
+ }
+ const char *SCI_METHOD DescribeProperty(const char *name) {
+ return osPerl.DescribeProperty(name);
+ }
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char *SCI_METHOD DescribeWordListSets() {
+ return osPerl.DescribeWordListSets();
+ }
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ 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);
+
+ void *SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactoryPerl() {
+ return new LexerPerl();
+ }
+};
+
+int SCI_METHOD LexerPerl::PropertySet(const char *key, const char *val) {
+ if (osPerl.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerPerl::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywords;
+ break;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerPerl::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
// keywords that forces /PATTERN/ at all times; should track vim's behaviour
WordList reWords;
@@ -307,9 +461,10 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
class HereDocCls { // Class to manage HERE doc sequence
public:
- int State; // 0: '<<' encountered
- // 1: collect the delimiter
- // 2: here doc text (lines after the delimiter)
+ int State;
+ // 0: '<<' encountered
+ // 1: collect the delimiter
+ // 2: here doc text (lines after the delimiter)
int Quote; // the char after '<<'
bool Quoted; // true if Quote in ('\'','"','`')
int DelimiterLength; // strlen(Delimiter)
@@ -333,7 +488,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
HereDocCls HereDoc; // TODO: FIFO for stacked here-docs
class QuoteCls { // Class to manage quote pairs
- public:
+ public:
int Rep;
int Count;
int Up, Down;
@@ -365,10 +520,10 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
// Includes strings (may be multi-line), numbers (additional state), format
// bodies, as well as POD sections.
if (initStyle == SCE_PL_HERE_Q
- || initStyle == SCE_PL_HERE_QQ
- || initStyle == SCE_PL_HERE_QX
- || initStyle == SCE_PL_FORMAT
- ) {
+ || initStyle == SCE_PL_HERE_QQ
+ || initStyle == SCE_PL_HERE_QX
+ || initStyle == SCE_PL_FORMAT
+ ) {
int delim = (initStyle == SCE_PL_FORMAT) ? SCE_PL_FORMAT_IDENT:SCE_PL_HERE_DELIM;
while ((startPos > 1) && (styler.StyleAt(startPos) != delim)) {
startPos--;
@@ -377,27 +532,27 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
initStyle = styler.StyleAt(startPos - 1);
}
if (initStyle == SCE_PL_STRING_Q
- || initStyle == SCE_PL_STRING_QQ
- || initStyle == SCE_PL_STRING_QX
- || initStyle == SCE_PL_STRING_QR
- || initStyle == SCE_PL_STRING_QW
- || initStyle == SCE_PL_REGEX
- || initStyle == SCE_PL_REGSUBST
- || initStyle == SCE_PL_STRING
- || initStyle == SCE_PL_BACKTICKS
- || initStyle == SCE_PL_CHARACTER
- || initStyle == SCE_PL_NUMBER
- || initStyle == SCE_PL_IDENTIFIER
- || initStyle == SCE_PL_ERROR
- || initStyle == SCE_PL_SUB_PROTOTYPE
- ) {
+ || initStyle == SCE_PL_STRING_QQ
+ || initStyle == SCE_PL_STRING_QX
+ || initStyle == SCE_PL_STRING_QR
+ || initStyle == SCE_PL_STRING_QW
+ || initStyle == SCE_PL_REGEX
+ || initStyle == SCE_PL_REGSUBST
+ || initStyle == SCE_PL_STRING
+ || initStyle == SCE_PL_BACKTICKS
+ || initStyle == SCE_PL_CHARACTER
+ || initStyle == SCE_PL_NUMBER
+ || initStyle == SCE_PL_IDENTIFIER
+ || initStyle == SCE_PL_ERROR
+ || initStyle == SCE_PL_SUB_PROTOTYPE
+ ) {
while ((startPos > 1) && (styler.StyleAt(startPos - 1) == initStyle)) {
startPos--;
}
initStyle = SCE_PL_DEFAULT;
} else if (initStyle == SCE_PL_POD
- || initStyle == SCE_PL_POD_VERB
- ) {
+ || initStyle == SCE_PL_POD_VERB
+ ) {
// POD backtracking finds preceeding blank lines and goes back past them
int ln = styler.GetLine(startPos);
if (ln > 0) {
@@ -435,187 +590,187 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
// Determine if the current state should terminate.
switch (sc.state) {
- case SCE_PL_OPERATOR:
+ case SCE_PL_OPERATOR:
+ sc.SetState(SCE_PL_DEFAULT);
+ backFlag = BACK_OPERATOR;
+ backPos = sc.currentPos;
+ break;
+ case SCE_PL_IDENTIFIER: // identifier, bareword, inputsymbol
+ if ((!setWord.Contains(sc.ch) && sc.ch != '\'')
+ || sc.Match('.', '.')
+ || sc.chPrev == '>') { // end of inputsymbol
sc.SetState(SCE_PL_DEFAULT);
- backFlag = BACK_OPERATOR;
- backPos = sc.currentPos;
- break;
- case SCE_PL_IDENTIFIER: // identifier, bareword, inputsymbol
- if ((!setWord.Contains(sc.ch) && sc.ch != '\'')
- || sc.Match('.', '.')
- || sc.chPrev == '>') { // end of inputsymbol
- sc.SetState(SCE_PL_DEFAULT);
- }
- break;
- case SCE_PL_WORD: // keyword, plus special cases
- if (!setWord.Contains(sc.ch)) {
- char s[100];
- sc.GetCurrent(s, sizeof(s));
- if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) {
- sc.ChangeState(SCE_PL_DATASECTION);
+ }
+ break;
+ case SCE_PL_WORD: // keyword, plus special cases
+ if (!setWord.Contains(sc.ch)) {
+ char s[100];
+ sc.GetCurrent(s, sizeof(s));
+ if ((strcmp(s, "__DATA__") == 0) || (strcmp(s, "__END__") == 0)) {
+ sc.ChangeState(SCE_PL_DATASECTION);
+ } else {
+ if ((strcmp(s, "format") == 0)) {
+ sc.SetState(SCE_PL_FORMAT_IDENT);
+ HereDoc.State = 0;
} else {
- if ((strcmp(s, "format") == 0)) {
- sc.SetState(SCE_PL_FORMAT_IDENT);
- HereDoc.State = 0;
- } else {
- sc.SetState(SCE_PL_DEFAULT);
- }
- backFlag = BACK_KEYWORD;
- backPos = sc.currentPos;
+ sc.SetState(SCE_PL_DEFAULT);
}
+ backFlag = BACK_KEYWORD;
+ backPos = sc.currentPos;
}
- break;
- case SCE_PL_SCALAR:
- case SCE_PL_ARRAY:
- case SCE_PL_HASH:
- case SCE_PL_SYMBOLTABLE:
- if (sc.Match(':', ':')) { // skip ::
+ }
+ break;
+ case SCE_PL_SCALAR:
+ case SCE_PL_ARRAY:
+ case SCE_PL_HASH:
+ case SCE_PL_SYMBOLTABLE:
+ if (sc.Match(':', ':')) { // skip ::
+ sc.Forward();
+ } else if (!setVar.Contains(sc.ch)) {
+ if (sc.LengthCurrent() == 1) {
+ // Special variable: $(, $_ etc.
sc.Forward();
- } else if (!setVar.Contains(sc.ch)) {
- if (sc.LengthCurrent() == 1) {
- // Special variable: $(, $_ etc.
- sc.Forward();
- }
- sc.SetState(SCE_PL_DEFAULT);
}
- break;
- case SCE_PL_NUMBER:
- // if no early break, number style is terminated at "(go through)"
- if (sc.ch == '.') {
- if (sc.chNext == '.') {
- // double dot is always an operator (go through)
- } else if (numState <= PERLNUM_FLOAT_EXP) {
- // non-decimal number or float exponent, consume next dot
- sc.SetState(SCE_PL_OPERATOR);
- break;
- } else { // decimal or vectors allows dots
- dotCount++;
- if (numState == PERLNUM_DECIMAL) {
- if (dotCount <= 1) // number with one dot in it
- break;
- if (IsADigit(sc.chNext)) { // really a vector
- numState = PERLNUM_VECTOR;
- break;
- }
- // number then dot (go through)
- } else if (IsADigit(sc.chNext)) // vectors
- break;
- // vector then dot (go through)
- }
- } else if (sc.ch == '_') {
- // permissive underscoring for number and vector literals
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ break;
+ case SCE_PL_NUMBER:
+ // if no early break, number style is terminated at "(go through)"
+ if (sc.ch == '.') {
+ if (sc.chNext == '.') {
+ // double dot is always an operator (go through)
+ } else if (numState <= PERLNUM_FLOAT_EXP) {
+ // non-decimal number or float exponent, consume next dot
+ sc.SetState(SCE_PL_OPERATOR);
break;
- } else if (numState == PERLNUM_DECIMAL) {
- if (sc.ch == 'E' || sc.ch == 'e') { // exponent, sign
- numState = PERLNUM_FLOAT_EXP;
- if (sc.chNext == '+' || sc.chNext == '-') {
- sc.Forward();
+ } else { // decimal or vectors allows dots
+ dotCount++;
+ if (numState == PERLNUM_DECIMAL) {
+ if (dotCount <= 1) // number with one dot in it
+ break;
+ if (IsADigit(sc.chNext)) { // really a vector
+ numState = PERLNUM_VECTOR;
+ break;
}
+ // number then dot (go through)
+ } else if (IsADigit(sc.chNext)) // vectors
break;
- } else if (IsADigit(sc.ch))
- break;
- // number then word (go through)
- } else if (numState == PERLNUM_HEX) {
- if (IsADigit(sc.ch, 16))
- break;
- } else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
- if (IsADigit(sc.ch)) // vector
- break;
- if (setWord.Contains(sc.ch) && dotCount == 0) { // change to word
- sc.ChangeState(SCE_PL_IDENTIFIER);
- break;
- }
- // vector then word (go through)
- } else if (IsADigit(sc.ch)) {
- if (numState == PERLNUM_FLOAT_EXP) {
- break;
- } else if (numState == PERLNUM_OCTAL) {
- if (sc.ch <= '7') break;
- } else if (numState == PERLNUM_BINARY) {
- if (sc.ch <= '1') break;
+ // vector then dot (go through)
+ }
+ } else if (sc.ch == '_') {
+ // permissive underscoring for number and vector literals
+ break;
+ } else if (numState == PERLNUM_DECIMAL) {
+ if (sc.ch == 'E' || sc.ch == 'e') { // exponent, sign
+ numState = PERLNUM_FLOAT_EXP;
+ if (sc.chNext == '+' || sc.chNext == '-') {
+ sc.Forward();
}
- // mark invalid octal, binary numbers (go through)
- numState = PERLNUM_BAD;
+ break;
+ } else if (IsADigit(sc.ch))
+ break;
+ // number then word (go through)
+ } else if (numState == PERLNUM_HEX) {
+ if (IsADigit(sc.ch, 16))
+ break;
+ } else if (numState == PERLNUM_VECTOR || numState == PERLNUM_V_VECTOR) {
+ if (IsADigit(sc.ch)) // vector
+ break;
+ if (setWord.Contains(sc.ch) && dotCount == 0) { // change to word
+ sc.ChangeState(SCE_PL_IDENTIFIER);
break;
}
- // complete current number or vector
- sc.ChangeState(actualNumStyle(numState));
- sc.SetState(SCE_PL_DEFAULT);
- break;
- case SCE_PL_COMMENTLINE:
- if (sc.atLineEnd) {
- sc.SetState(SCE_PL_DEFAULT);
+ // vector then word (go through)
+ } else if (IsADigit(sc.ch)) {
+ if (numState == PERLNUM_FLOAT_EXP) {
+ break;
+ } else if (numState == PERLNUM_OCTAL) {
+ if (sc.ch <= '7') break;
+ } else if (numState == PERLNUM_BINARY) {
+ if (sc.ch <= '1') break;
}
+ // mark invalid octal, binary numbers (go through)
+ numState = PERLNUM_BAD;
break;
- case SCE_PL_HERE_DELIM:
- if (HereDoc.State == 0) { // '<<' encountered
- int delim_ch = sc.chNext;
- int ws_skip = 0;
- HereDoc.State = 1; // pre-init HERE doc class
- HereDoc.Quote = sc.chNext;
- HereDoc.Quoted = false;
- HereDoc.DelimiterLength = 0;
- HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
- if (IsASpaceOrTab(delim_ch)) {
- // skip whitespace; legal only for quoted delimiters
- unsigned int i = sc.currentPos + 1;
- while ((i < endPos) && IsASpaceOrTab(delim_ch)) {
- i++;
- delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
- }
- ws_skip = i - sc.currentPos - 1;
+ }
+ // complete current number or vector
+ sc.ChangeState(actualNumStyle(numState));
+ sc.SetState(SCE_PL_DEFAULT);
+ break;
+ case SCE_PL_COMMENTLINE:
+ if (sc.atLineEnd) {
+ sc.SetState(SCE_PL_DEFAULT);
+ }
+ break;
+ case SCE_PL_HERE_DELIM:
+ if (HereDoc.State == 0) { // '<<' encountered
+ int delim_ch = sc.chNext;
+ int ws_skip = 0;
+ HereDoc.State = 1; // pre-init HERE doc class
+ HereDoc.Quote = sc.chNext;
+ HereDoc.Quoted = false;
+ HereDoc.DelimiterLength = 0;
+ HereDoc.Delimiter[HereDoc.DelimiterLength] = '\0';
+ if (IsASpaceOrTab(delim_ch)) {
+ // skip whitespace; legal only for quoted delimiters
+ unsigned int i = sc.currentPos + 1;
+ while ((i < endPos) && IsASpaceOrTab(delim_ch)) {
+ i++;
+ delim_ch = static_cast<unsigned char>(styler.SafeGetCharAt(i));
}
- if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') {
- // a quoted here-doc delimiter; skip any whitespace
- sc.Forward(ws_skip + 1);
- HereDoc.Quote = delim_ch;
- HereDoc.Quoted = true;
- } else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))
- || ws_skip > 0) {
- // left shift << or <<= operator cases
- // restore position if operator
- sc.ChangeState(SCE_PL_OPERATOR);
+ ws_skip = i - sc.currentPos - 1;
+ }
+ if (delim_ch == '\'' || delim_ch == '"' || delim_ch == '`') {
+ // a quoted here-doc delimiter; skip any whitespace
+ sc.Forward(ws_skip + 1);
+ HereDoc.Quote = delim_ch;
+ HereDoc.Quoted = true;
+ } else if ((ws_skip == 0 && setNonHereDoc.Contains(sc.chNext))
+ || ws_skip > 0) {
+ // left shift << or <<= operator cases
+ // restore position if operator
+ sc.ChangeState(SCE_PL_OPERATOR);
+ sc.ForwardSetState(SCE_PL_DEFAULT);
+ backFlag = BACK_OPERATOR;
+ backPos = sc.currentPos;
+ HereDoc.State = 0;
+ } else {
+ // specially handle initial '\' for identifier
+ if (ws_skip == 0 && HereDoc.Quote == '\\')
+ sc.Forward();
+ // an unquoted here-doc delimiter, no special handling
+ // (cannot be prefixed by spaces/tabs), or
+ // symbols terminates; deprecated zero-length delimiter
+ }
+ } else if (HereDoc.State == 1) { // collect the delimiter
+ backFlag = BACK_NONE;
+ if (HereDoc.Quoted) { // a quoted here-doc delimiter
+ if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
sc.ForwardSetState(SCE_PL_DEFAULT);
- backFlag = BACK_OPERATOR;
- backPos = sc.currentPos;
- HereDoc.State = 0;
- } else {
- // specially handle initial '\' for identifier
- if (ws_skip == 0 && HereDoc.Quote == '\\')
+ } else if (!sc.atLineEnd) {
+ if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote
sc.Forward();
- // an unquoted here-doc delimiter, no special handling
- // (cannot be prefixed by spaces/tabs), or
- // symbols terminates; deprecated zero-length delimiter
- }
- } else if (HereDoc.State == 1) { // collect the delimiter
- backFlag = BACK_NONE;
- if (HereDoc.Quoted) { // a quoted here-doc delimiter
- if (sc.ch == HereDoc.Quote) { // closing quote => end of delimiter
- sc.ForwardSetState(SCE_PL_DEFAULT);
- } else if (!sc.atLineEnd) {
- if (sc.Match('\\', static_cast<char>(HereDoc.Quote))) { // escaped quote
- sc.Forward();
- }
- if (sc.ch != '\r') { // skip CR if CRLF
- HereDoc.Append(sc.ch);
- }
}
- } else { // an unquoted here-doc delimiter
- if (setHereDocDelim.Contains(sc.ch)) {
+ if (sc.ch != '\r') { // skip CR if CRLF
HereDoc.Append(sc.ch);
- } else {
- sc.SetState(SCE_PL_DEFAULT);
}
}
- if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
- sc.SetState(SCE_PL_ERROR);
- HereDoc.State = 0;
+ } else { // an unquoted here-doc delimiter
+ if (setHereDocDelim.Contains(sc.ch)) {
+ HereDoc.Append(sc.ch);
+ } else {
+ sc.SetState(SCE_PL_DEFAULT);
}
}
- break;
- case SCE_PL_HERE_Q:
- case SCE_PL_HERE_QQ:
- case SCE_PL_HERE_QX: {
+ if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) {
+ sc.SetState(SCE_PL_ERROR);
+ HereDoc.State = 0;
+ }
+ }
+ break;
+ case SCE_PL_HERE_Q:
+ case SCE_PL_HERE_QQ:
+ case SCE_PL_HERE_QX: {
// also implies HereDoc.State == 2
sc.Complete();
while (!sc.atLineEnd)
@@ -627,9 +782,10 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
backFlag = BACK_NONE;
HereDoc.State = 0;
}
- } break;
- case SCE_PL_POD:
- case SCE_PL_POD_VERB: {
+ }
+ break;
+ case SCE_PL_POD:
+ case SCE_PL_POD_VERB: {
unsigned int fw = sc.currentPos;
int ln = styler.GetLine(fw);
if (sc.atLineStart && sc.Match("=cut")) { // end of POD
@@ -657,86 +813,87 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
pod = SCE_PL_POD;
} else {
if (pod == SCE_PL_POD_VERB // still part of current paragraph
- && (styler.GetLineState(ln - 1) == SCE_PL_POD)) {
+ && (styler.GetLineState(ln - 1) == SCE_PL_POD)) {
pod = SCE_PL_POD;
styler.SetLineState(ln, pod);
} else if (pod == SCE_PL_POD
- && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) {
+ && (styler.GetLineState(ln - 1) == SCE_PL_POD_VERB)) {
pod = SCE_PL_POD_VERB;
styler.SetLineState(ln, pod);
}
sc.SetState(pod);
}
sc.Forward(fw - sc.currentPos); // commit style
- } break;
- case SCE_PL_REGEX:
- case SCE_PL_STRING_QR:
- if (Quote.Rep <= 0) {
- if (!setModifiers.Contains(sc.ch))
- sc.SetState(SCE_PL_DEFAULT);
- } else if (!Quote.Up && !IsASpace(sc.ch)) {
- Quote.Open(sc.ch);
- } else if (sc.ch == '\\' && Quote.Up != '\\') {
- sc.Forward();
- } else if (sc.ch == Quote.Down) {
- Quote.Count--;
- if (Quote.Count == 0)
- Quote.Rep--;
- } else if (sc.ch == Quote.Up) {
- Quote.Count++;
- }
- break;
- case SCE_PL_REGSUBST:
- if (Quote.Rep <= 0) {
- if (!setModifiers.Contains(sc.ch))
- sc.SetState(SCE_PL_DEFAULT);
- } else if (!Quote.Up && !IsASpace(sc.ch)) {
+ }
+ break;
+ case SCE_PL_REGEX:
+ case SCE_PL_STRING_QR:
+ if (Quote.Rep <= 0) {
+ if (!setModifiers.Contains(sc.ch))
+ sc.SetState(SCE_PL_DEFAULT);
+ } else if (!Quote.Up && !IsASpace(sc.ch)) {
+ Quote.Open(sc.ch);
+ } else if (sc.ch == '\\' && Quote.Up != '\\') {
+ sc.Forward();
+ } else if (sc.ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0)
+ Quote.Rep--;
+ } else if (sc.ch == Quote.Up) {
+ Quote.Count++;
+ }
+ break;
+ case SCE_PL_REGSUBST:
+ if (Quote.Rep <= 0) {
+ if (!setModifiers.Contains(sc.ch))
+ sc.SetState(SCE_PL_DEFAULT);
+ } else if (!Quote.Up && !IsASpace(sc.ch)) {
+ Quote.Open(sc.ch);
+ } else if (sc.ch == '\\' && Quote.Up != '\\') {
+ sc.Forward();
+ } else if (Quote.Count == 0 && Quote.Rep == 1) {
+ // We matched something like s(...) or tr{...}, Perl 5.10
+ // appears to allow almost any character for use as the
+ // next delimiters. Whitespace and comments are accepted in
+ // between, but we'll limit to whitespace here.
+ // For '#', if no whitespace in between, it's a delimiter.
+ if (IsASpace(sc.ch)) {
+ // Keep going
+ } else if (sc.ch == '#' && IsASpaceOrTab(sc.chPrev)) {
+ sc.SetState(SCE_PL_DEFAULT);
+ } else {
Quote.Open(sc.ch);
- } else if (sc.ch == '\\' && Quote.Up != '\\') {
- sc.Forward();
- } else if (Quote.Count == 0 && Quote.Rep == 1) {
- // We matched something like s(...) or tr{...}, Perl 5.10
- // appears to allow almost any character for use as the
- // next delimiters. Whitespace and comments are accepted in
- // between, but we'll limit to whitespace here.
- // For '#', if no whitespace in between, it's a delimiter.
- if (IsASpace(sc.ch)) {
- // Keep going
- } else if (sc.ch == '#' && IsASpaceOrTab(sc.chPrev)) {
- sc.SetState(SCE_PL_DEFAULT);
- } else {
- Quote.Open(sc.ch);
- }
- } else if (sc.ch == Quote.Down) {
- Quote.Count--;
- if (Quote.Count == 0)
- Quote.Rep--;
- if (Quote.Up == Quote.Down)
- Quote.Count++;
- } else if (sc.ch == Quote.Up) {
- Quote.Count++;
}
- break;
- case SCE_PL_STRING_Q:
- case SCE_PL_STRING_QQ:
- case SCE_PL_STRING_QX:
- case SCE_PL_STRING_QW:
- case SCE_PL_STRING:
- case SCE_PL_CHARACTER:
- case SCE_PL_BACKTICKS:
- if (!Quote.Down && !IsASpace(sc.ch)) {
- Quote.Open(sc.ch);
- } else if (sc.ch == '\\' && Quote.Up != '\\') {
- sc.Forward();
- } else if (sc.ch == Quote.Down) {
- Quote.Count--;
- if (Quote.Count == 0)
- sc.ForwardSetState(SCE_PL_DEFAULT);
- } else if (sc.ch == Quote.Up) {
+ } else if (sc.ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0)
+ Quote.Rep--;
+ if (Quote.Up == Quote.Down)
Quote.Count++;
- }
- break;
- case SCE_PL_SUB_PROTOTYPE: {
+ } else if (sc.ch == Quote.Up) {
+ Quote.Count++;
+ }
+ break;
+ case SCE_PL_STRING_Q:
+ case SCE_PL_STRING_QQ:
+ case SCE_PL_STRING_QX:
+ case SCE_PL_STRING_QW:
+ case SCE_PL_STRING:
+ case SCE_PL_CHARACTER:
+ case SCE_PL_BACKTICKS:
+ if (!Quote.Down && !IsASpace(sc.ch)) {
+ Quote.Open(sc.ch);
+ } else if (sc.ch == '\\' && Quote.Up != '\\') {
+ sc.Forward();
+ } else if (sc.ch == Quote.Down) {
+ Quote.Count--;
+ if (Quote.Count == 0)
+ sc.ForwardSetState(SCE_PL_DEFAULT);
+ } else if (sc.ch == Quote.Up) {
+ Quote.Count++;
+ }
+ break;
+ case SCE_PL_SUB_PROTOTYPE: {
int i = 0;
// forward scan; must all be valid proto characters
while (setSubPrototype.Contains(sc.GetRelative(i)))
@@ -749,8 +906,9 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
sc.ChangeState(SCE_PL_OPERATOR);
sc.SetState(SCE_PL_DEFAULT);
}
- } break;
- case SCE_PL_FORMAT: {
+ }
+ break;
+ case SCE_PL_FORMAT: {
sc.Complete();
while (!sc.atLineEnd)
sc.Forward();
@@ -758,42 +916,43 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
sc.GetCurrent(s, sizeof(s));
if (isMatch(".", s))
sc.SetState(SCE_PL_DEFAULT);
- } break;
- case SCE_PL_ERROR:
- break;
+ }
+ break;
+ case SCE_PL_ERROR:
+ break;
}
// Needed for specific continuation styles (one follows the other)
switch (sc.state) {
// continued from SCE_PL_WORD
- case SCE_PL_FORMAT_IDENT:
- // occupies HereDoc state 3 to avoid clashing with HERE docs
- if (IsASpaceOrTab(sc.ch)) { // skip whitespace
- sc.ChangeState(SCE_PL_DEFAULT);
- while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+ case SCE_PL_FORMAT_IDENT:
+ // occupies HereDoc state 3 to avoid clashing with HERE docs
+ if (IsASpaceOrTab(sc.ch)) { // skip whitespace
+ sc.ChangeState(SCE_PL_DEFAULT);
+ while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+ sc.Forward();
+ sc.SetState(SCE_PL_FORMAT_IDENT);
+ }
+ if (setFormatStart.Contains(sc.ch)) { // identifier or '='
+ if (sc.ch != '=') {
+ do {
sc.Forward();
- sc.SetState(SCE_PL_FORMAT_IDENT);
+ } while (setFormat.Contains(sc.ch));
}
- if (setFormatStart.Contains(sc.ch)) { // identifier or '='
- if (sc.ch != '=') {
- do {
- sc.Forward();
- } while (setFormat.Contains(sc.ch));
- }
- while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
- sc.Forward();
- if (sc.ch == '=') {
- sc.ForwardSetState(SCE_PL_DEFAULT);
- HereDoc.State = 3;
- } else {
- // invalid indentifier; inexact fallback, but hey
- sc.ChangeState(SCE_PL_IDENTIFIER);
- sc.SetState(SCE_PL_DEFAULT);
- }
+ while (IsASpaceOrTab(sc.ch) && !sc.atLineEnd)
+ sc.Forward();
+ if (sc.ch == '=') {
+ sc.ForwardSetState(SCE_PL_DEFAULT);
+ HereDoc.State = 3;
} else {
- sc.ChangeState(SCE_PL_DEFAULT); // invalid indentifier
+ // invalid indentifier; inexact fallback, but hey
+ sc.ChangeState(SCE_PL_IDENTIFIER);
+ sc.SetState(SCE_PL_DEFAULT);
}
- backFlag = BACK_NONE;
- break;
+ } else {
+ sc.ChangeState(SCE_PL_DEFAULT); // invalid indentifier
+ }
+ backFlag = BACK_NONE;
+ break;
}
// Must check end of HereDoc states here before default state is handled
@@ -810,9 +969,15 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
sc.ChangeState(SCE_PL_ERROR);
}
switch (HereDoc.Quote) {
- case '\'': st_new = SCE_PL_HERE_Q ; break;
- case '"' : st_new = SCE_PL_HERE_QQ; break;
- case '`' : st_new = SCE_PL_HERE_QX; break;
+ case '\'':
+ st_new = SCE_PL_HERE_Q ;
+ break;
+ case '"' :
+ st_new = SCE_PL_HERE_QQ;
+ break;
+ case '`' :
+ st_new = SCE_PL_HERE_QX;
+ break;
}
} else {
if (HereDoc.Quote == '\\')
@@ -829,7 +994,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
// Determine if a new state should be entered.
if (sc.state == SCE_PL_DEFAULT) {
if (IsADigit(sc.ch) ||
- (IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) {
+ (IsADigit(sc.chNext) && (sc.ch == '.' || sc.ch == 'v'))) {
sc.SetState(SCE_PL_NUMBER);
backFlag = BACK_NONE;
numState = PERLNUM_DECIMAL;
@@ -875,8 +1040,8 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
sc.Forward();
fw++;
} else if (sc.ch == 'q' && setQDelim.Contains(sc.chNext)
- && !setWord.Contains(sc.GetRelative(2))) {
- if (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ);
+ && !setWord.Contains(sc.GetRelative(2))) {
+ if (sc.chNext == 'q') sc.ChangeState(SCE_PL_STRING_QQ);
else if (sc.chNext == 'x') sc.ChangeState(SCE_PL_STRING_QX);
else if (sc.chNext == 'r') sc.ChangeState(SCE_PL_STRING_QR);
else sc.ChangeState(SCE_PL_STRING_QW); // sc.chNext == 'w'
@@ -884,8 +1049,8 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
sc.Forward();
fw++;
} else if (sc.ch == 'x' && (sc.chNext == '=' || // repetition
- !setWord.Contains(sc.chNext) ||
- (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) {
+ !setWord.Contains(sc.chNext) ||
+ (IsADigit(sc.chPrev) && IsADigit(sc.chNext)))) {
sc.ChangeState(SCE_PL_OPERATOR);
}
// if potentially a keyword, scan forward and grab word, then check
@@ -974,7 +1139,7 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
} else {
int bkstyle = styler.StyleAt(bk);
int bkch = static_cast<unsigned char>(styler.SafeGetCharAt(bk));
- switch(bkstyle) {
+ switch (bkstyle) {
case SCE_PL_OPERATOR:
preferRE = true;
if (bkch == ')' || bkch == ']') {
@@ -984,17 +1149,17 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
// needed to test for variables like ${}, @{} etc.
bkstyle = styleBeforeBracePair(styler, bk);
if (bkstyle == SCE_PL_SCALAR
- || bkstyle == SCE_PL_ARRAY
- || bkstyle == SCE_PL_HASH
- || bkstyle == SCE_PL_SYMBOLTABLE
- || bkstyle == SCE_PL_OPERATOR) {
+ || bkstyle == SCE_PL_ARRAY
+ || bkstyle == SCE_PL_HASH
+ || bkstyle == SCE_PL_SYMBOLTABLE
+ || bkstyle == SCE_PL_OPERATOR) {
preferRE = false;
}
} else if (bkch == '+' || bkch == '-') {
if (bkch == static_cast<unsigned char>(styler.SafeGetCharAt(bk - 1))
- && bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2)))
- // exceptions for operators: unary suffixes ++, --
- preferRE = false;
+ && bkch != static_cast<unsigned char>(styler.SafeGetCharAt(bk - 2)))
+ // exceptions for operators: unary suffixes ++, --
+ preferRE = false;
}
break;
case SCE_PL_IDENTIFIER:
@@ -1047,7 +1212,8 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
preferRE = false;
}
break;
- // other styles uses the default, preferRE=false
+
+ // other styles uses the default, preferRE=false
case SCE_PL_POD:
case SCE_PL_HERE_Q:
case SCE_PL_HERE_QQ:
@@ -1121,15 +1287,15 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
}
}
} else if (sc.ch == '=' // POD
- && setPOD.Contains(sc.chNext)
- && sc.atLineStart) {
+ && setPOD.Contains(sc.chNext)
+ && sc.atLineStart) {
sc.SetState(SCE_PL_POD);
backFlag = BACK_NONE;
} else if (sc.ch == '-' && setWordStart.Contains(sc.chNext)) { // extended '-' cases
unsigned int bk = sc.currentPos;
unsigned int fw = 2;
if (setSingleCharOp.Contains(sc.chNext) && // file test operators
- !setWord.Contains(sc.GetRelative(2))) {
+ !setWord.Contains(sc.GetRelative(2))) {
sc.SetState(SCE_PL_WORD);
} else {
// nominally a minus and bareword; find extent of bareword
@@ -1165,39 +1331,37 @@ static void ColourisePerlDoc(unsigned int startPos, int length, int initStyle,
}
}
sc.Complete();
-}
-
-static bool IsCommentLine(int line, Accessor &styler) {
- int pos = styler.LineStart(line);
- int eol_pos = styler.LineStart(line + 1) - 1;
- for (int i = pos; i < eol_pos; i++) {
- char ch = styler[i];
- int style = styler.StyleAt(i);
- if (ch == '#' && style == SCE_PL_COMMENTLINE)
- return true;
- else if (!IsASpaceOrTab(ch))
- return false;
+ if (sc.state == SCE_PL_HERE_Q
+ || sc.state == SCE_PL_HERE_QQ
+ || sc.state == SCE_PL_HERE_QX
+ || sc.state == SCE_PL_FORMAT) {
+ styler.ChangeLexerState(sc.currentPos, styler.Length());
}
- return false;
+ sc.Complete();
}
-static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
- Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- // Custom folding of POD and packages
+#define PERL_HEADFOLD_SHIFT 4
+#define PERL_HEADFOLD_MASK 0xF0
- // property fold.perl.pod
- // Enable folding Pod blocks when using the Perl lexer.
- bool foldPOD = styler.GetPropertyInt("fold.perl.pod", 1) != 0;
+void SCI_METHOD LexerPerl::Fold(unsigned int startPos, int length, int /* initStyle */, IDocument *pAccess) {
- // property fold.perl.package
- // Enable folding packages when using the Perl lexer.
- bool foldPackage = styler.GetPropertyInt("fold.perl.package", 1) != 0;
+ if (!options.fold)
+ return;
+
+ LexAccessor styler(pAccess);
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
+
+ // Backtrack to previous line in case need to fix its fold status
+ if (startPos > 0) {
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ startPos = styler.LineStart(lineCurrent);
+ }
+ }
+
int levelPrev = SC_FOLDLEVELBASE;
if (lineCurrent > 0)
levelPrev = styler.LevelAt(lineCurrent - 1) >> 16;
@@ -1207,67 +1371,118 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
int styleNext = styler.StyleAt(startPos);
// Used at end of line to determine if the line was a package definition
bool isPackageLine = false;
- bool isPodHeading = false;
+ int podHeading = 0;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
int style = styleNext;
styleNext = styler.StyleAt(i + 1);
+ int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
bool atLineStart = ((chPrev == '\r') || (chPrev == '\n')) || i == 0;
// Comment folding
- if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
- {
+ if (options.foldComment && atEOL && IsCommentLine(lineCurrent, styler)) {
if (!IsCommentLine(lineCurrent - 1, styler)
- && IsCommentLine(lineCurrent + 1, styler))
+ && IsCommentLine(lineCurrent + 1, styler))
levelCurrent++;
else if (IsCommentLine(lineCurrent - 1, styler)
- && !IsCommentLine(lineCurrent+1, styler))
+ && !IsCommentLine(lineCurrent + 1, styler))
levelCurrent--;
}
+ // {} [] block folding
if (style == SCE_PL_OPERATOR) {
if (ch == '{') {
+ if (options.foldAtElse && levelCurrent < levelPrev)
+ --levelPrev;
levelCurrent++;
} else if (ch == '}') {
levelCurrent--;
}
+ if (ch == '[') {
+ if (options.foldAtElse && levelCurrent < levelPrev)
+ --levelPrev;
+ levelCurrent++;
+ } else if (ch == ']') {
+ levelCurrent--;
+ }
}
- // Custom POD folding
- if (foldPOD && atLineStart) {
- int stylePrevCh = (i) ? styler.StyleAt(i - 1):SCE_PL_DEFAULT;
+ // POD folding
+ if (options.foldPOD && atLineStart) {
if (style == SCE_PL_POD) {
if (stylePrevCh != SCE_PL_POD && stylePrevCh != SCE_PL_POD_VERB)
levelCurrent++;
else if (styler.Match(i, "=cut"))
- levelCurrent--;
+ levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;
else if (styler.Match(i, "=head"))
- isPodHeading = true;
+ podHeading = PodHeadingLevel(i, styler);
} else if (style == SCE_PL_DATASECTION) {
- if (ch == '=' && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)
+ if (ch == '=' && isascii(chNext) && isalpha(chNext) && levelCurrent == SC_FOLDLEVELBASE)
levelCurrent++;
else if (styler.Match(i, "=cut") && levelCurrent > SC_FOLDLEVELBASE)
- levelCurrent--;
+ levelCurrent = (levelCurrent & ~PERL_HEADFOLD_MASK) - 1;
else if (styler.Match(i, "=head"))
- isPodHeading = true;
+ podHeading = PodHeadingLevel(i, styler);
// if package used or unclosed brace, level > SC_FOLDLEVELBASE!
// reset needed as level test is vs. SC_FOLDLEVELBASE
- else if (styler.Match(i, "__END__"))
+ else if (stylePrevCh != SCE_PL_DATASECTION)
levelCurrent = SC_FOLDLEVELBASE;
}
}
- // Custom package folding
- if (foldPackage && atLineStart) {
- if (style == SCE_PL_WORD && styler.Match(i, "package")) {
+ // package folding
+ if (options.foldPackage && atLineStart) {
+ if (IsPackageLine(lineCurrent, styler)
+ && !IsPackageLine(lineCurrent + 1, styler))
isPackageLine = true;
+ }
+
+ //heredoc folding
+ switch (style) {
+ case SCE_PL_HERE_QQ :
+ case SCE_PL_HERE_Q :
+ case SCE_PL_HERE_QX :
+ switch (stylePrevCh) {
+ case SCE_PL_HERE_QQ :
+ case SCE_PL_HERE_Q :
+ case SCE_PL_HERE_QX :
+ //do nothing;
+ break;
+ default :
+ levelCurrent++;
+ break;
+ }
+ break;
+ default:
+ switch (stylePrevCh) {
+ case SCE_PL_HERE_QQ :
+ case SCE_PL_HERE_Q :
+ case SCE_PL_HERE_QX :
+ levelCurrent--;
+ break;
+ default :
+ //do nothing;
+ break;
+ }
+ break;
+ }
+
+ //explicit folding
+ if (options.foldCommentExplicit && style == SCE_PL_COMMENTLINE && ch == '#') {
+ if (chNext == '{') {
+ levelCurrent++;
+ } else if (levelCurrent > SC_FOLDLEVELBASE && chNext == '}') {
+ levelCurrent--;
}
}
if (atEOL) {
int lev = levelPrev;
- if (isPodHeading) {
- lev = levelPrev - 1;
+ // POD headings occupy bits 7-4, leaving some breathing room for
+ // non-standard practice -- POD sections stuck in blocks, etc.
+ if (podHeading > 0) {
+ levelCurrent = (lev & ~PERL_HEADFOLD_MASK) | (podHeading << PERL_HEADFOLD_SHIFT);
+ lev = levelCurrent - 1;
lev |= SC_FOLDLEVELHEADERFLAG;
- isPodHeading = false;
+ podHeading = 0;
}
// Check if line was a package declaration
// because packages need "special" treatment
@@ -1277,7 +1492,7 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
isPackageLine = false;
}
lev |= levelCurrent << 16;
- if (visibleChars == 0 && foldCompact)
+ if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if ((levelCurrent > levelPrev) && (visibleChars > 0))
lev |= SC_FOLDLEVELHEADERFLAG;
@@ -1297,9 +1512,4 @@ static void FoldPerlDoc(unsigned int startPos, int length, int, WordList *[],
styler.SetLevel(lineCurrent, levelPrev | flagsNext);
}
-static const char * const perlWordListDesc[] = {
- "Keywords",
- 0
-};
-
-LexerModule lmPerl(SCLEX_PERL, ColourisePerlDoc, "perl", FoldPerlDoc, perlWordListDesc, 8);
+LexerModule lmPerl(SCLEX_PERL, LexerPerl::LexerFactoryPerl, "perl", perlWordListDesc, 8);
diff --git a/plugins/scintilla/scintilla/LexPowerPro.cxx b/plugins/scintilla/scintilla/LexPowerPro.cxx
index 9320baf..89bce58 100644
--- a/plugins/scintilla/scintilla/LexPowerPro.cxx
+++ b/plugins/scintilla/scintilla/LexPowerPro.cxx
@@ -3,42 +3,45 @@
// PowerPro utility, written by Bruce Switzer, is available from http://powerpro.webeddie.com
// PowerPro lexer is written by Christopher Bean (cbean cb-software net)
//
-// Lexer code heavily borrowed from:
+// Lexer code heavily borrowed from:
// LexAU3.cxx by Jos van der Zande
// LexCPP.cxx by Neil Hodgson
// LexVB.cxx by Neil Hodgson
//
// Changes:
// 2008-10-25 - Initial release
-// 2008-10-26 - Changed how <name> is hilighted in 'function <name>' so that
+// 2008-10-26 - Changed how <name> is hilighted in 'function <name>' so that
// local isFunction = "" and local functions = "" don't get falsely highlighted
-// 2008-12-14 - Added bounds checking for szKeyword and szDo
+// 2008-12-14 - Added bounds checking for szFirstWord and szDo
// - Replaced SetOfCharacters with CharacterSet
// - Made sure that CharacterSet::Contains is passed only positive values
-// - Made sure that the return value of Accessor::SafeGetCharAt is positive before
-// passsing to functions that require positive values like isspacechar()
+// - Made sure that the return value of Accessor::SafeGetCharAt is positive before
+// passing to functions that require positive values like isspacechar()
// - Removed unused visibleChars processing from ColourisePowerProDoc()
-// - Fixed bug with folding logic where line continuations didn't end where
+// - Fixed bug with folding logic where line continuations didn't end where
// they were supposed to
// - Moved all helper functions to the top of the file
-//
+// 2010-06-03 - Added onlySpaces variable to allow the @function and ;comment styles to be indented
+// - Modified HasFunction function to be a bit more robust
+// - Renamed HasFunction function to IsFunction
+// - Cleanup
// Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
-#include <ctype.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <stdlib.h>
#include <string.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.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;
@@ -48,65 +51,81 @@ static inline bool IsStreamCommentStyle(int style) {
return style == SCE_POWERPRO_COMMENTBLOCK;
}
+static inline bool IsLineEndChar(unsigned char ch) {
+ return ch == 0x0a //LF
+ || ch == 0x0c //FF
+ || ch == 0x0d; //CR
+}
+
static bool IsContinuationLine(unsigned int szLine, Accessor &styler)
{
- int nsPos = styler.LineStart(szLine);
- int nePos = styler.LineStart(szLine + 1) - 2;
- while (nsPos < nePos)
+ int startPos = styler.LineStart(szLine);
+ int endPos = styler.LineStart(szLine + 1) - 2;
+ while (startPos < endPos)
{
- int stylech = styler.StyleAt(nsPos);
+ char stylech = styler.StyleAt(startPos);
if (!(stylech == SCE_POWERPRO_COMMENTBLOCK)) {
- char ch = styler.SafeGetCharAt(nePos);
- char chPrev = styler.SafeGetCharAt(nePos-1);
- char chPrevPrev = styler.SafeGetCharAt(nePos-2);
- if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) ) {
- if (chPrevPrev == ';' && chPrev == ';' && ch == '+')
- return true;
- else
- return false;
+ char ch = styler.SafeGetCharAt(endPos);
+ char chPrev = styler.SafeGetCharAt(endPos - 1);
+ char chPrevPrev = styler.SafeGetCharAt(endPos - 2);
+ if (ch > 0 && chPrev > 0 && chPrevPrev > 0 && !isspacechar(ch) && !isspacechar(chPrev) && !isspacechar(chPrevPrev) )
+ return (chPrevPrev == ';' && chPrev == ';' && ch == '+');
}
- }
- nePos--; // skip to next char
+ endPos--; // skip to next char
}
return false;
}
// Routine to find first none space on the current line and return its Style
-// needed for comment lines not starting on pos 1
-static int GetStyleFirstWord(unsigned int szLine, Accessor &styler)
+// needed for comment lines not starting on pos 1
+static int GetStyleFirstWord(int szLine, Accessor &styler)
{
- int nsPos = styler.LineStart(szLine);
- int nePos = styler.LineStart(szLine+1) - 1;
- char ch = styler.SafeGetCharAt(nsPos);
-
- while (ch > 0 && isspacechar(ch) && nsPos < nePos)
- {
- nsPos++; // skip to next char
- ch = styler.SafeGetCharAt(nsPos);
+ int startPos = styler.LineStart(szLine);
+ int endPos = styler.LineStart(szLine + 1) - 1;
+ char ch = styler.SafeGetCharAt(startPos);
+ while (ch > 0 && isspacechar(ch) && startPos < endPos)
+ {
+ startPos++; // skip to next char
+ ch = styler.SafeGetCharAt(startPos);
}
- return styler.StyleAt(nsPos);
+ return styler.StyleAt(startPos);
}
//returns true if there is a function to highlight
//used to highlight <name> in 'function <name>'
-static bool HasFunction(Accessor &styler, unsigned int currentPos) {
-
- //check for presence of 'function '
- return (styler.SafeGetCharAt(currentPos) == ' '
- && tolower(styler.SafeGetCharAt(currentPos-1)) == 'n'
- && tolower(styler.SafeGetCharAt(currentPos-2)) == 'o'
- && tolower(styler.SafeGetCharAt(currentPos-3)) == 'i'
- && tolower(styler.SafeGetCharAt(currentPos-4)) == 't'
- && tolower(styler.SafeGetCharAt(currentPos-5)) == 'c'
- && tolower(styler.SafeGetCharAt(currentPos-6)) == 'n'
- && tolower(styler.SafeGetCharAt(currentPos-7)) == 'u'
- && tolower(styler.SafeGetCharAt(currentPos-8)) == 'f'
- //only allow 'function ' to appear at the beginning of a line
- && (styler.SafeGetCharAt(currentPos-9) == '\n'
- || styler.SafeGetCharAt(currentPos-9) == '\r'
- || (styler.SafeGetCharAt(currentPos -9, '\0')) == '\0') //is the first line
- );
+//note:
+// sample line (without quotes): "\tfunction asdf()
+// currentPos will be the position of 'a'
+static bool IsFunction(Accessor &styler, unsigned int currentPos) {
+
+ const char function[10] = "function "; //10 includes \0
+ unsigned int numberOfCharacters = sizeof(function) - 1;
+ unsigned int position = currentPos - numberOfCharacters;
+
+ //compare each character with the letters in the function array
+ //return false if ALL don't match
+ for (unsigned int i = 0; i < numberOfCharacters; i++) {
+ char c = styler.SafeGetCharAt(position++);
+ if (c != function[i])
+ return false;
+ }
+
+ //make sure that there are only spaces (or tabs) between the beginning
+ //of the line and the function declaration
+ position = currentPos - numberOfCharacters - 1; //-1 to move to char before 'function'
+ for (unsigned int j = 0; j < 16; j++) { //check up to 16 preceeding characters
+ char c = styler.SafeGetCharAt(position--, '\0'); //if can't read char, return NUL (past beginning of document)
+ if (c <= 0) //reached beginning of document
+ return true;
+ if (c > 0 && IsLineEndChar(c))
+ return true;
+ else if (c > 0 && !IsASpaceOrTab(c))
+ return false;
+ }
+
+ //fall-through
+ return false;
}
static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
@@ -116,22 +135,24 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
WordList &keywords4 = *keywordlists[3];
-
- //define the character sets
+
+ //define the character sets
CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
StyleContext sc(startPos, length, initStyle, styler);
char s_save[100]; //for last line highlighting
-
+
+ //are there only spaces between the first letter of the line and the beginning of the line
+ bool onlySpaces = true;
+
for (; sc.More(); sc.Forward()) {
-
- // **********************************************
+
// save the total current word for eof processing
char s[100];
sc.GetCurrentLowered(s, sizeof(s));
-
- if ((sc.ch > 0) && setWord.Contains(sc.ch))
+
+ if ((sc.ch > 0) && setWord.Contains(sc.ch))
{
strcpy(s_save,s);
int tp = strlen(s_save);
@@ -140,8 +161,6 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
s_save[tp+1] = '\0';
}
}
- // **********************************************
- //
if (sc.atLineStart) {
if (sc.state == SCE_POWERPRO_DOUBLEQUOTEDSTRING) {
@@ -156,12 +175,12 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
case SCE_POWERPRO_OPERATOR:
sc.SetState(SCE_POWERPRO_DEFAULT);
break;
-
+
case SCE_POWERPRO_NUMBER:
if (!IsADigit(sc.ch))
sc.SetState(SCE_POWERPRO_DEFAULT);
-
+
break;
case SCE_POWERPRO_IDENTIFIER:
@@ -173,6 +192,7 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
} else {
sc.GetCurrentLowered(s, sizeof(s));
}
+
if (keywords.InList(s)) {
sc.ChangeState(SCE_POWERPRO_WORD);
} else if (keywords2.InList(s)) {
@@ -256,9 +276,9 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
}
}
break;
-
+
case SCE_POWERPRO_FUNCTION:
- if (sc.ch == '\r' || sc.ch == '\n' || sc.ch == ' ' || sc.ch == '(') {
+ if (isspacechar(sc.ch) || sc.ch == '(') {
sc.SetState(SCE_POWERPRO_DEFAULT);
}
break;
@@ -276,20 +296,20 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
sc.SetState(SCE_POWERPRO_ALTQUOTE);
sc.Forward();
}
- } else if (HasFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>'
- sc.SetState(SCE_POWERPRO_FUNCTION);
- } else if (sc.ch == '@' && sc.atLineStart) { //alternate function definition [label]
+ } else if (IsFunction(styler, sc.currentPos)) { //highlight <name> in 'function <name>'
+ sc.SetState(SCE_POWERPRO_FUNCTION);
+ } else if (onlySpaces && sc.ch == '@') { //alternate function definition [label]
sc.SetState(SCE_POWERPRO_FUNCTION);
} else if ((sc.ch > 0) && (setWordStart.Contains(sc.ch) || (sc.ch == '?'))) {
sc.SetState(SCE_POWERPRO_IDENTIFIER);
- } else if (sc.Match(";;+")) {
+ } else if (sc.Match(";;+")) {
sc.SetState(SCE_POWERPRO_LINECONTINUE);
} else if (sc.Match('/', '*')) {
sc.SetState(SCE_POWERPRO_COMMENTBLOCK);
sc.Forward(); // Eat the * so it isn't used for the end of the comment
} else if (sc.Match('/', '/')) {
sc.SetState(SCE_POWERPRO_COMMENTLINE);
- } else if (sc.atLineStart && sc.ch == ';') { //legacy comment that can only appear at the beginning of a line
+ } else if (onlySpaces && sc.ch == ';') { //legacy comment that can only have blank space in front of it
sc.SetState(SCE_POWERPRO_COMMENTLINE);
} else if (sc.Match(";;")) {
sc.SetState(SCE_POWERPRO_COMMENTLINE);
@@ -301,10 +321,19 @@ static void ColourisePowerProDoc(unsigned int startPos, int length, int initStyl
sc.SetState(SCE_POWERPRO_OPERATOR);
}
}
+
+ //maintain a record of whether or not all the preceding characters on
+ //a line are space characters
+ if (onlySpaces && !IsASpaceOrTab(sc.ch))
+ onlySpaces = false;
+
+ //reset when starting a new line
+ if (sc.atLineEnd)
+ onlySpaces = true;
}
//*************************************
- // Colourize the last word correctly
+ // Colourize the last word correctly
//*************************************
if (sc.state == SCE_POWERPRO_IDENTIFIER)
{
@@ -337,7 +366,9 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
CharacterSet setWordStart(CharacterSet::setAlpha, "_@", 0x80, true);
CharacterSet setWord(CharacterSet::setAlphaNum, "._", 0x80, true);
- bool isFoldingAll = true; //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)
+ //used to tell if we're recursively folding the whole document, or just a small piece (ie: if statement or 1 function)
+ bool isFoldingAll = true;
+
int endPos = startPos + length;
int lastLine = styler.GetLine(styler.Length()); //used to help fold the last line correctly
@@ -345,7 +376,7 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldInComment = styler.GetPropertyInt("fold.comment") == 2;
bool foldCompact = true;
-
+
// Backtrack to previous line in case need to fix its fold status
int lineCurrent = styler.GetLine(startPos);
if (startPos > 0) {
@@ -355,153 +386,156 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
startPos = styler.LineStart(lineCurrent);
}
}
- // vars for style of previous/current/next lines
+ // vars for style of previous/current/next lines
int style = GetStyleFirstWord(lineCurrent,styler);
int stylePrev = 0;
-
+
// find the first previous line without continuation character at the end
- while ((lineCurrent > 0 && IsContinuationLine(lineCurrent,styler)) ||
- (lineCurrent > 1 && IsContinuationLine(lineCurrent-1,styler))) {
+ while ((lineCurrent > 0 && IsContinuationLine(lineCurrent, styler))
+ || (lineCurrent > 1 && IsContinuationLine(lineCurrent - 1, styler))) {
lineCurrent--;
startPos = styler.LineStart(lineCurrent);
}
+
if (lineCurrent > 0) {
stylePrev = GetStyleFirstWord(lineCurrent-1,styler);
}
+
// vars for getting first word to check for keywords
- bool FirstWordStart = false;
- bool FirstWordEnd = false;
-
- const unsigned int KEYWORD_MAX = 10;
- char szKeyword[KEYWORD_MAX]="";
- unsigned int szKeywordlen = 0;
-
+ bool isFirstWordStarted = false;
+ bool isFirstWordEnded = false;
+
+ const unsigned int FIRST_WORD_MAX_LEN = 10;
+ char szFirstWord[FIRST_WORD_MAX_LEN] = "";
+ unsigned int firstWordLen = 0;
+
char szDo[3]="";
int szDolen = 0;
- bool DoFoundLast = false;
-
+ bool isDoLastWord = false;
+
// var for indentlevel
int levelCurrent = SC_FOLDLEVELBASE;
- if (lineCurrent > 0) {
+ if (lineCurrent > 0)
levelCurrent = styler.LevelAt(lineCurrent-1) >> 16;
- }
int levelNext = levelCurrent;
-
+
int visibleChars = 0;
int functionCount = 0;
-
+
char chNext = styler.SafeGetCharAt(startPos);
char chPrev = '\0';
char chPrevPrev = '\0';
char chPrevPrevPrev = '\0';
-
+
for (int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
-
- if ((ch > 0) && setWord.Contains(ch)) {
+
+ if ((ch > 0) && setWord.Contains(ch))
visibleChars++;
- }
-
+
// get the syle for the current character neede to check in comment
int stylech = styler.StyleAt(i);
-
- // get first word for the line for indent check max 9 characters
- if (FirstWordStart && (!(FirstWordEnd))) {
- if ((ch > 0) && !setWord.Contains(ch)) {
- FirstWordEnd = true;
+
+ // start the capture of the first word
+ if (!isFirstWordStarted && (ch > 0)) {
+ if (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/') {
+ isFirstWordStarted = true;
+ if (firstWordLen < FIRST_WORD_MAX_LEN - 1) {
+ szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));
+ szFirstWord[firstWordLen] = '\0';
+ }
}
- else if (szKeywordlen < KEYWORD_MAX - 1) {
- szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
- szKeyword[szKeywordlen] = '\0';
+ } // continue capture of the first word on the line
+ else if (isFirstWordStarted && !isFirstWordEnded && (ch > 0)) {
+ if (!setWord.Contains(ch)) {
+ isFirstWordEnded = true;
}
- }
-
- // start the capture of the first word
- if (!(FirstWordStart)) {
- if ((ch > 0) && (setWord.Contains(ch) || setWordStart.Contains(ch) || ch == ';' || ch == '/')) {
- FirstWordStart = true;
- if (szKeywordlen < KEYWORD_MAX - 1) {
- szKeyword[szKeywordlen++] = static_cast<char>(tolower(ch));
- szKeyword[szKeywordlen] = '\0';
- }
+ else if (firstWordLen < (FIRST_WORD_MAX_LEN - 1)) {
+ szFirstWord[firstWordLen++] = static_cast<char>(tolower(ch));
+ szFirstWord[firstWordLen] = '\0';
}
}
- // only process this logic when not in comment section
+
if (stylech != SCE_POWERPRO_COMMENTLINE) {
- if (DoFoundLast) {
- if (DoFoundLast && (ch > 0) && setWord.Contains(ch)) {
- DoFoundLast = false;
- }
- }
- // find out if the word "do" is the last on a "if" line
- if (FirstWordEnd && strcmp(szKeyword,"if") == 0) {
+
+ //reset isDoLastWord if we find a character(ignoring spaces) after 'do'
+ if (isDoLastWord && (ch > 0) && setWord.Contains(ch))
+ isDoLastWord = false;
+
+ // --find out if the word "do" is the last on a "if" line--
+ // collect each letter and put it into a buffer 2 chars long
+ // if we end up with "do" in the buffer when we reach the end of
+ // the line, "do" was the last word on the line
+ if ((ch > 0) && isFirstWordEnded && strcmp(szFirstWord, "if") == 0) {
if (szDolen == 2) {
szDo[0] = szDo[1];
szDo[1] = static_cast<char>(tolower(ch));
szDo[2] = '\0';
- if (strcmp(szDo,"do") == 0 ) {
- DoFoundLast = true;
- }
- }
- else if (szDolen < 2) {
+
+ if (strcmp(szDo, "do") == 0)
+ isDoLastWord = true;
+
+ } else if (szDolen < 2) {
szDo[szDolen++] = static_cast<char>(tolower(ch));
szDo[szDolen] = '\0';
}
}
}
- // End of Line found so process the information
- if ((ch == '\r' && chNext != '\n') || (ch == '\n') || (i == endPos)) {
-
+ // End of Line found so process the information
+ if ((ch == '\r' && chNext != '\n') // \r\n
+ || ch == '\n' // \n
+ || i == endPos) { // end of selection
+
// **************************
// Folding logic for Keywords
// **************************
-
+
// if a keyword is found on the current line and the line doesn't end with ;;+ (continuation)
// and we are not inside a commentblock.
- if (szKeywordlen > 0 &&
- (!(chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev ==';')) &&
- ((!(IsStreamCommentStyle(style)) || foldInComment)) ) {
-
+ if (firstWordLen > 0
+ && chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev !=';'
+ && (!IsStreamCommentStyle(style) || foldInComment) ) {
+
// only fold "if" last keyword is "then" (else its a one line if)
- if (strcmp(szKeyword,"if") == 0 && DoFoundLast) {
+ if (strcmp(szFirstWord, "if") == 0 && isDoLastWord)
levelNext++;
- }
- // create new fold for these words
- if (strcmp(szKeyword,"for") == 0) {
+
+ // create new fold for these words
+ if (strcmp(szFirstWord, "for") == 0)
levelNext++;
- }
-
+
//handle folding for functions/labels
//Note: Functions and labels don't have an explicit end like [end function]
// 1. functions/labels end at the start of another function
// 2. functions/labels end at the end of the file
- if ((strcmp(szKeyword,"function") == 0) || (szKeywordlen > 0 && szKeyword[0] == '@')) {
+ if ((strcmp(szFirstWord, "function") == 0) || (firstWordLen > 0 && szFirstWord[0] == '@')) {
if (isFoldingAll) { //if we're folding the whole document (recursivly by lua script)
-
+
if (functionCount > 0) {
levelCurrent--;
} else {
levelNext++;
}
- functionCount++;
-
+ functionCount++;
+
} else { //if just folding a small piece (by clicking on the minus sign next to the word)
levelCurrent--;
}
}
-
+
// end the fold for these words before the current line
- if (strcmp(szKeyword,"endif") == 0 || strcmp(szKeyword,"endfor") == 0) {
+ if (strcmp(szFirstWord, "endif") == 0 || strcmp(szFirstWord, "endfor") == 0) {
levelNext--;
levelCurrent--;
}
- // end the fold for these words before the current line and Start new fold
- if (strcmp(szKeyword,"else") == 0 || strcmp(szKeyword,"elseif") == 0 ) {
+
+ // end the fold for these words before the current line and Start new fold
+ if (strcmp(szFirstWord, "else") == 0 || strcmp(szFirstWord, "elseif") == 0 )
levelCurrent--;
- }
+
}
// Preprocessor and Comment folding
int styleNext = GetStyleFirstWord(lineCurrent + 1,styler);
@@ -510,20 +544,19 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
// Folding logic for Comment blocks
// *********************************
if (foldComment && IsStreamCommentStyle(style)) {
+
// Start of a comment block
- if (!(stylePrev==style) && IsStreamCommentStyle(styleNext) && styleNext==style) {
+ if (stylePrev != style && IsStreamCommentStyle(styleNext) && styleNext == style) {
levelNext++;
- }
- // fold till the last line for normal comment lines
- else if (IsStreamCommentStyle(stylePrev)
- && !(styleNext == SCE_POWERPRO_COMMENTLINE)
- && stylePrev == SCE_POWERPRO_COMMENTLINE
+ } // fold till the last line for normal comment lines
+ else if (IsStreamCommentStyle(stylePrev)
+ && styleNext != SCE_POWERPRO_COMMENTLINE
+ && stylePrev == SCE_POWERPRO_COMMENTLINE
&& style == SCE_POWERPRO_COMMENTLINE) {
levelNext--;
- }
- // fold till the one but last line for Blockcomment lines
- else if (IsStreamCommentStyle(stylePrev)
- && !(styleNext == SCE_POWERPRO_COMMENTBLOCK)
+ } // fold till the one but last line for Blockcomment lines
+ else if (IsStreamCommentStyle(stylePrev)
+ && styleNext != SCE_POWERPRO_COMMENTBLOCK
&& style == SCE_POWERPRO_COMMENTBLOCK) {
levelNext--;
levelCurrent--;
@@ -534,12 +567,10 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
int lev = levelUse | levelNext << 16;
if (visibleChars == 0 && foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
- if (levelUse < levelNext) {
+ if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
- }
- if (lev != styler.LevelAt(lineCurrent)) {
+ if (lev != styler.LevelAt(lineCurrent))
styler.SetLevel(lineCurrent, lev);
- }
// reset values for the next line
lineCurrent++;
@@ -547,20 +578,18 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
style = styleNext;
levelCurrent = levelNext;
visibleChars = 0;
-
+
// if the last characters are ;;+ then don't reset since the line continues on the next line.
- if (chPrev == '+' && chPrevPrev == ';' && chPrevPrevPrev == ';') {
- //do nothing
- } else {
- szKeywordlen = 0;
+ if (chPrev != '+' && chPrevPrev != ';' && chPrevPrevPrev != ';') {
+ firstWordLen = 0;
szDolen = 0;
- FirstWordStart = false;
- FirstWordEnd = false;
- DoFoundLast = false;
- //blank out keyword
- for (unsigned int i = 0; i < KEYWORD_MAX; i++) {
- szKeyword[i] = '\0';
- }
+ isFirstWordStarted = false;
+ isFirstWordEnded = false;
+ isDoLastWord = false;
+
+ //blank out first word
+ for (unsigned int i = 0; i < FIRST_WORD_MAX_LEN; i++)
+ szFirstWord[i] = '\0';
}
}
@@ -569,11 +598,10 @@ static void FoldPowerProDoc(unsigned int startPos, int length, int, WordList *[]
chPrevPrevPrev = chPrevPrev;
chPrevPrev = chPrev;
chPrev = ch;
- visibleChars++;
}
}
- //close folds on the last line - without this a 'phantom'
+ //close folds on the last line - without this a 'phantom'
//fold can appear when an open fold is on the last line
//this can occur because functions and labels don't have an explicit end
if (lineCurrent >= lastLine) {
@@ -598,3 +626,5 @@ static void ColourisePowerProDocWrapper(unsigned int startPos, int length, int i
}
LexerModule lmPowerPro(SCLEX_POWERPRO, ColourisePowerProDocWrapper, "powerpro", FoldPowerProDoc, powerProWordLists);
+
+
diff --git a/plugins/scintilla/scintilla/LexPowerShell.cxx b/plugins/scintilla/scintilla/LexPowerShell.cxx
index d16ba98..7f741fc 100644
--- a/plugins/scintilla/scintilla/LexPowerShell.cxx
+++ b/plugins/scintilla/scintilla/LexPowerShell.cxx
@@ -7,18 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -26,7 +29,7 @@ using namespace Scintilla;
// Extended to accept accented characters
static inline bool IsAWordChar(int ch) {
- return ch >= 0x80 || isalnum(ch) || ch == '-';
+ return ch >= 0x80 || isalnum(ch) || ch == '-' || ch == '_';
}
static void ColourisePowerShellDoc(unsigned int startPos, int length, int initStyle,
@@ -35,6 +38,8 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
WordList &keywords = *keywordlists[0];
WordList &keywords2 = *keywordlists[1];
WordList &keywords3 = *keywordlists[2];
+ WordList &keywords4 = *keywordlists[3];
+ WordList &keywords5 = *keywordlists[4];
styler.StartAt(startPos);
@@ -46,6 +51,10 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
if (sc.atLineEnd) {
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
+ } else if (sc.state == SCE_POWERSHELL_COMMENTSTREAM) {
+ if (sc.ch == '>' && sc.chPrev == '#') {
+ sc.ForwardSetState(SCE_POWERSHELL_DEFAULT);
+ }
} else if (sc.state == SCE_POWERSHELL_STRING) {
// This is a doubles quotes string
if (sc.ch == '\"') {
@@ -79,6 +88,10 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
sc.ChangeState(SCE_POWERSHELL_CMDLET);
} else if (keywords3.InList(s)) {
sc.ChangeState(SCE_POWERSHELL_ALIAS);
+ } else if (keywords4.InList(s)) {
+ sc.ChangeState(SCE_POWERSHELL_FUNCTION);
+ } else if (keywords5.InList(s)) {
+ sc.ChangeState(SCE_POWERSHELL_USER1);
}
sc.SetState(SCE_POWERSHELL_DEFAULT);
}
@@ -88,6 +101,8 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
if (sc.state == SCE_POWERSHELL_DEFAULT) {
if (sc.ch == '#') {
sc.SetState(SCE_POWERSHELL_COMMENT);
+ } else if (sc.ch == '<' && sc.chNext == '#') {
+ sc.SetState(SCE_POWERSHELL_COMMENTSTREAM);
} else if (sc.ch == '\"') {
sc.SetState(SCE_POWERSHELL_STRING);
} else if (sc.ch == '\'') {
@@ -109,8 +124,9 @@ static void ColourisePowerShellDoc(unsigned int startPos, int length, int initSt
// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
-static void FoldPowerShellDoc(unsigned int startPos, int length, int,
+static void FoldPowerShellDoc(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
+ bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldAtElse = styler.GetPropertyInt("fold.at.else", 0) != 0;
unsigned int endPos = startPos + length;
@@ -123,10 +139,12 @@ static void FoldPowerShellDoc(unsigned int startPos, int length, int,
int levelNext = levelCurrent;
char chNext = styler[startPos];
int styleNext = styler.StyleAt(startPos);
+ int style = initStyle;
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
- int style = styleNext;
+ int stylePrev = style;
+ style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
if (style == SCE_POWERSHELL_OPERATOR) {
@@ -140,6 +158,12 @@ static void FoldPowerShellDoc(unsigned int startPos, int length, int,
} else if (ch == '}') {
levelNext--;
}
+ } else if (foldComment && style == SCE_POWERSHELL_COMMENTSTREAM) {
+ if (stylePrev != SCE_POWERSHELL_COMMENTSTREAM) {
+ levelNext++;
+ } else if (styleNext != SCE_POWERSHELL_COMMENTSTREAM) {
+ levelNext--;
+ }
}
if (!IsASpace(ch))
visibleChars++;
@@ -168,6 +192,8 @@ static const char * const powershellWordLists[] = {
"Commands",
"Cmdlets",
"Aliases",
+ "Functions",
+ "User1",
0
};
diff --git a/plugins/scintilla/scintilla/LexProgress.cxx b/plugins/scintilla/scintilla/LexProgress.cxx
index 9e1940e..2031720 100644
--- a/plugins/scintilla/scintilla/LexProgress.cxx
+++ b/plugins/scintilla/scintilla/LexProgress.cxx
@@ -13,18 +13,21 @@ Support more than 6 comments levels
**/
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -47,7 +50,7 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
WordList &keywords2 = *keywordlists[1]; // block opening keywords, only when SentenceStart
WordList &keywords3 = *keywordlists[2]; // block opening keywords
//WordList &keywords4 = *keywordlists[3]; // preprocessor keywords. Not implemented
-
+
int visibleChars = 0;
int mask;
@@ -180,7 +183,7 @@ static void Colourise4glDoc(unsigned int startPos, int length, int initStyle, Wo
} else if (isoperator(static_cast<char>(sc.ch))) {
/* This code allows highlight of handles. Alas, it would cause the phrase "last-event:function"
to be recognized as a BlockBegin */
-
+
if (sc.ch == ':')
sc.SetState(SCE_4GL_OPERATOR & SetSentenceStart);
/* else */
diff --git a/plugins/scintilla/scintilla/LexPython.cxx b/plugins/scintilla/scintilla/LexPython.cxx
index 897a136..70db1ec 100644
--- a/plugins/scintilla/scintilla/LexPython.cxx
+++ b/plugins/scintilla/scintilla/LexPython.cxx
@@ -7,25 +7,28 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
/* kwCDef, kwCTypeName only used for Cython */
-enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName };
+enum kwType { kwOther, kwClass, kwDef, kwImport, kwCDef, kwCTypeName, kwCPDef };
static const int indicatorWhitespace = 1;
@@ -36,7 +39,7 @@ static bool IsPyComment(Accessor &styler, int pos, int len) {
enum literalsAllowed { litNone=0, litU=1, litB=2};
static bool IsPyStringTypeChar(int ch, literalsAllowed allowed) {
- return
+ return
((allowed & litB) && (ch == 'b' || ch == 'B')) ||
((allowed & litU) && (ch == 'u' || ch == 'U'));
}
@@ -136,13 +139,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
WordList &keywords2 = *keywordlists[1];
// property tab.timmy.whinge.level
- // For Python code, checks whether indenting is consistent.
- // The default, 0 turns off indentation checking,
- // 1 checks whether each line is potentially inconsistent with the previous line,
- // 2 checks whether any space characters occur before a tab character in the indentation,
- // 3 checks whether any spaces are in the indentation, and
+ // For Python code, checks whether indenting is consistent.
+ // The default, 0 turns off indentation checking,
+ // 1 checks whether each line is potentially inconsistent with the previous line,
+ // 2 checks whether any space characters occur before a tab character in the indentation,
+ // 3 checks whether any spaces are in the indentation, and
// 4 checks for any tab characters in the indentation.
- // 1 is a good level to use.
+ // 1 is a good level to use.
const int whingeLevel = styler.GetPropertyInt("tab.timmy.whinge.level");
// property lexer.python.literals.binary
@@ -243,7 +246,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
style = SCE_P_CLASSNAME;
} else if (kwLast == kwDef) {
style = SCE_P_DEFNAME;
- } else if (kwLast == kwCDef) {
+ } else if (kwLast == kwCDef || kwLast == kwCPDef) {
int pos = sc.currentPos;
unsigned char ch = styler.SafeGetCharAt(pos, '\0');
while (ch != '\0') {
@@ -274,11 +277,13 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
kwLast = kwImport;
else if (0 == strcmp(s, "cdef"))
kwLast = kwCDef;
+ else if (0 == strcmp(s, "cpdef"))
+ kwLast = kwCPDef;
else if (0 == strcmp(s, "cimport"))
kwLast = kwImport;
- else if (kwLast != kwCDef)
+ else if (kwLast != kwCDef && kwLast != kwCPDef)
kwLast = kwOther;
- } else if (kwLast != kwCDef) {
+ } else if (kwLast != kwCDef && kwLast != kwCPDef) {
kwLast = kwOther;
}
}
@@ -334,8 +339,8 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
indentGood = true;
}
- // One cdef line, clear kwLast only at end of line
- if (kwLast == kwCDef && sc.atLineEnd) {
+ // One cdef or cpdef line, clear kwLast only at end of line
+ if ((kwLast == kwCDef || kwLast == kwCPDef) && sc.atLineEnd) {
kwLast = kwOther;
}
@@ -353,7 +358,7 @@ static void ColourisePyDoc(unsigned int startPos, int length, int initStyle,
if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {
base_n_number = true;
sc.SetState(SCE_P_NUMBER);
- } else if (sc.ch == '0' &&
+ } else if (sc.ch == '0' &&
(sc.chNext == 'o' || sc.chNext == 'O' || sc.chNext == 'b' || sc.chNext == 'B')) {
if (base2or8Literals) {
base_n_number = true;
@@ -507,7 +512,7 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
}
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
- const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
+ const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments);
// Now set all the indent levels on the lines we skipped
// Do this from end to start. Once we encounter one line
@@ -538,7 +543,7 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
}
// Set fold header on non-quote/non-comment line
- if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG) ) {
+ if (!quote && !comment && !(indentCurrent & SC_FOLDLEVELWHITEFLAG)) {
if ((indentCurrent & SC_FOLDLEVELNUMBERMASK) < (indentNext & SC_FOLDLEVELNUMBERMASK))
lev |= SC_FOLDLEVELHEADERFLAG;
}
@@ -558,7 +563,7 @@ static void FoldPyDoc(unsigned int startPos, int length, int /*initStyle - unuse
//styler.SetLevel(lineCurrent, indentCurrent);
}
-static const char * const pythonWordListDesc[] = {
+static const char *const pythonWordListDesc[] = {
"Keywords",
"Highlighted identifiers",
0
diff --git a/plugins/scintilla/scintilla/LexR.cxx b/plugins/scintilla/scintilla/LexR.cxx
index 67e779f..d18fffb 100644
--- a/plugins/scintilla/scintilla/LexR.cxx
+++ b/plugins/scintilla/scintilla/LexR.cxx
@@ -8,18 +8,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -77,9 +80,9 @@ static void ColouriseRDoc(unsigned int startPos, int length, int initStyle, Word
sc.SetState(SCE_R_DEFAULT);
}
} else if (sc.state == SCE_R_IDENTIFIER) {
- if (!IsAWordChar(sc.ch) || (sc.ch == '.')) {
+ if (!IsAWordChar(sc.ch)) {
char s[100];
- sc.GetCurrentLowered(s, sizeof(s));
+ sc.GetCurrent(s, sizeof(s));
if (keywords.InList(s)) {
sc.ChangeState(SCE_R_KWORD);
} else if (keywords2.InList(s)) {
diff --git a/plugins/scintilla/scintilla/LexRebol.cxx b/plugins/scintilla/scintilla/LexRebol.cxx
index 7139b8d..7d000df 100644
--- a/plugins/scintilla/scintilla/LexRebol.cxx
+++ b/plugins/scintilla/scintilla/LexRebol.cxx
@@ -13,18 +13,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
diff --git a/plugins/scintilla/scintilla/LexRuby.cxx b/plugins/scintilla/scintilla/LexRuby.cxx
old mode 100755
new mode 100644
index 8d6dc90..4545bfa
--- a/plugins/scintilla/scintilla/LexRuby.cxx
+++ b/plugins/scintilla/scintilla/LexRuby.cxx
@@ -7,18 +7,22 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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
@@ -78,7 +82,7 @@ static bool followsDot(unsigned int pos, Accessor &styler) {
return false;
}
break;
-
+
case SCE_RB_OPERATOR:
return styler[pos] == '.';
@@ -118,7 +122,7 @@ static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywor
else if (keywords.InList(s) && !followsDot(start - 1, styler)) {
if (keywordIsAmbiguous(s)
&& keywordIsModifier(s, start, styler)) {
-
+
// Demoted keywords are colored as keywords,
// but do not affect changes in indentation.
//
@@ -127,7 +131,7 @@ static int ClassifyWordRb(unsigned int start, unsigned int end, WordList &keywor
// 2. <<stmt if test>> : demoted
// 3. <<lhs = if ...>> : normal: start a new indent level
// 4. <<obj.if = 10>> : color as identifer, since it follows '.'
-
+
chAttr = SCE_RB_WORD_DEMOTED;
} else {
chAttr = SCE_RB_WORD;
@@ -224,7 +228,7 @@ static bool currLineContainsHereDelims(int& startPos,
// Leave the pointers where they are -- there are no
// here doc delims on the current line, even if
// the EOL isn't default style
-
+
return false;
} else {
styler.Flush();
@@ -276,7 +280,7 @@ class QuoteCls {
}
return *this;
}
-
+
};
@@ -352,7 +356,7 @@ static int skipWhitespace(int startPos,
}
return endPos;
}
-
+
// This routine looks for false positives like
// undef foo, <<
// There aren't too many.
@@ -362,7 +366,7 @@ static int skipWhitespace(int startPos,
static bool sureThisIsHeredoc(int iPrev,
Accessor &styler,
char *prevWord) {
-
+
// Not so fast, since Ruby's so dynamic. Check the context
// to make sure we're OK.
int prevStyle;
@@ -453,7 +457,7 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
styler.Flush();
const bool definitely_not_a_here_doc = true;
const bool looks_like_a_here_doc = false;
-
+
// Find the first word after some whitespace
int firstWordPosn = skipWhitespace(lineStartPosn, lt2StartPos, styler);
if (firstWordPosn >= lt2StartPos) {
@@ -531,7 +535,7 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
target_quote = styler[j];
j += 1;
}
-
+
if (isSafeAlnum(styler[j])) {
// Init target_end because some compilers think it won't
// be initialized by the time it's used
@@ -549,7 +553,7 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
// And for now make sure that it's a newline
// don't handle arbitrary expressions yet
-
+
target_end = j;
if (target_quote) {
// Now we can move to the character after the string delimiter.
@@ -592,7 +596,7 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
}
//todo: if we aren't looking at a stdio character,
-// move to the start of the first line that is not in a
+// move to the start of the first line that is not in a
// multi-line construct
static void synchronizeDocStart(unsigned int& startPos,
@@ -610,7 +614,7 @@ static void synchronizeDocStart(unsigned int& startPos,
// Don't do anything else with these.
return;
}
-
+
int pos = startPos;
// Quick way to characterize each line
int lineStart;
@@ -651,7 +655,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
// Lexer for Ruby often has to backtrack to start of current style to determine
// which characters are being used as quotes, how deeply nested is the
// start position and what the termination string is for here documents
-
+
WordList &keywords = *keywordlists[0];
class HereDocCls {
@@ -674,7 +678,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
CanBeIndented = false;
}
};
- HereDocCls HereDoc;
+ HereDocCls HereDoc;
QuoteCls Quote;
@@ -750,7 +754,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
i += 1;
continue;
}
-
+
// skip on DOS/Windows
//No, don't, because some things will get tagged on,
// so we won't recognize keywords, for example
@@ -759,7 +763,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
continue;
}
#endif
-
+
if (HereDoc.State == 1 && isEOLChar(ch)) {
// Begin of here-doc (the line after the here-doc delimiter):
HereDoc.State = 2;
@@ -973,6 +977,15 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
} else if (preferRE && !isSafeWordcharOrHigh(chNext)) {
// Ruby doesn't allow high bit chars here,
// but the editor host might
+ Quote.New();
+ state = SCE_RB_STRING_QQ;
+ Quote.Open(chNext);
+ advance_char(i, ch, chNext, chNext2); // pass by ref
+ have_string = true;
+ } else if (!isSafeWordcharOrHigh(chNext) && !iswhitespace(chNext) && !isEOLChar(chNext)) {
+ // Ruby doesn't allow high bit chars here,
+ // but the editor host might
+ Quote.New();
state = SCE_RB_STRING_QQ;
Quote.Open(chNext);
advance_char(i, ch, chNext, chNext2); // pass by ref
@@ -1003,7 +1016,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
// So if we don't have one of these chars,
// we aren't ending an object exp'n, and ops
// like : << / are unary operators.
-
+
if (ch == '{') {
++brace_counts;
preferRE = true;
@@ -1035,7 +1048,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
// Default accessor treats '.' as word-chars,
// but we don't for now.
-
+
if (ch == '='
&& isSafeWordcharOrHigh(chPrev)
&& (chNext == '('
@@ -1066,11 +1079,11 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
case SCE_RB_WORD:
preferRE = RE_CanFollowKeyword(prevWord);
break;
-
+
case SCE_RB_WORD_DEMOTED:
preferRE = true;
break;
-
+
case SCE_RB_IDENTIFIER:
if (isMatch(styler, lengthDoc, wordStartPos, "print")) {
preferRE = true;
@@ -1087,7 +1100,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
// We might be redefining an operator-method
preferRE = false;
}
- // And if it's the first
+ // And if it's the first
redo_char(i, ch, chNext, chNext2, state); // pass by ref
}
}
@@ -1124,6 +1137,10 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
}
} else if (isSafeAlnumOrHigh(ch) || ch == '_') {
// Keep going
+ } else if (ch == '.' && chNext == '.') {
+ ++numDots;
+ styler.ColourTo(i - 1, state);
+ redo_char(i, ch, chNext, chNext2, state); // pass by ref
} else if (ch == '.' && ++numDots == 1) {
// Keep going
} else {
@@ -1141,7 +1158,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
// See the comment for SCE_RB_HERE_DELIM in LexPerl.cxx
// Slightly different: if we find an immediate '-',
// the target can appear indented.
-
+
if (HereDoc.State == 0) { // '<<' encountered
HereDoc.State = 1;
HereDoc.DelimiterLength = 0;
@@ -1157,7 +1174,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
preferRE = false;
} else {
HereDoc.Quote = ch;
-
+
if (ch == '\'' || ch == '"' || ch == '`') {
HereDoc.Quoted = true;
HereDoc.Delimiter[0] = '\0';
@@ -1291,7 +1308,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
} else if (ch == Quote.Up) {
// Only if close quoter != open quoter
Quote.Count++;
-
+
} else if (ch == '#' ) {
if (chNext == '{'
&& inner_string_count < INNER_STRINGS_MAX_COUNT) {
@@ -1336,7 +1353,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
}
}
// Quotes of all kinds...
- } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ ||
+ } else if (state == SCE_RB_STRING_Q || state == SCE_RB_STRING_QQ ||
state == SCE_RB_STRING_QX || state == SCE_RB_STRING_QW ||
state == SCE_RB_STRING || state == SCE_RB_CHARACTER ||
state == SCE_RB_BACKTICKS) {
@@ -1373,7 +1390,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
advance_char(i, ch, chNext, chNext2);
}
}
-
+
if (state == SCE_RB_ERROR) {
break;
}
@@ -1389,7 +1406,7 @@ static void ColouriseRbDoc(unsigned int startPos, int length, int initStyle,
}
// Helper functions for folding, disambiguation keywords
-// Assert that there are no high-bit chars
+// Assert that there are no high-bit chars
static void getPrevWord(int pos,
char *prevWord,
@@ -1430,7 +1447,7 @@ static bool keywordIsAmbiguous(const char *prevWord)
// Demote keywords in the following conditions:
// if, while, unless, until modify a statement
-// do after a while or until, as a noise word (like then after if)
+// do after a while or until, as a noise word (like then after if)
static bool keywordIsModifier(const char *word,
int pos,
@@ -1439,10 +1456,32 @@ static bool keywordIsModifier(const char *word,
if (word[0] == 'd' && word[1] == 'o' && !word[2]) {
return keywordDoStartsLoop(pos, styler);
}
- char ch;
+ char ch, chPrev, chPrev2;
int style = SCE_RB_DEFAULT;
int lineStart = styler.GetLine(pos);
int lineStartPosn = styler.LineStart(lineStart);
+ // We want to step backwards until we don't care about the current
+ // position. But first move lineStartPosn back behind any
+ // continuations immediately above word.
+ while (lineStartPosn > 0) {
+ ch = styler[lineStartPosn-1];
+ if (ch == '\n' || ch == '\r') {
+ chPrev = styler.SafeGetCharAt(lineStartPosn-2);
+ chPrev2 = styler.SafeGetCharAt(lineStartPosn-3);
+ lineStart = styler.GetLine(lineStartPosn-1);
+ // If we find a continuation line, include it in our analysis.
+ if (chPrev == '\\') {
+ lineStartPosn = styler.LineStart(lineStart);
+ } else if (ch == '\n' && chPrev == '\r' && chPrev2 == '\\') {
+ lineStartPosn = styler.LineStart(lineStart);
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+
styler.Flush();
while (--pos >= lineStartPosn) {
style = actual_style(styler.StyleAt(pos));
@@ -1453,14 +1492,27 @@ static bool keywordIsModifier(const char *word,
// Scintilla's LineStart() and GetLine() routines aren't
// platform-independent, so if we have text prepared with
// a different system we can't rely on it.
- return false;
+
+ // Also, lineStartPosn may have been moved to more than one
+ // line above word's line while pushing past continuations.
+ chPrev = styler.SafeGetCharAt(pos - 1);
+ chPrev2 = styler.SafeGetCharAt(pos - 2);
+ if (chPrev == '\\') {
+ pos-=1; // gloss over the "\\"
+ //continue
+ } else if (ch == '\n' && chPrev == '\r' && chPrev2 == '\\') {
+ pos-=2; // gloss over the "\\\r"
+ //continue
+ } else {
+ return false;
+ }
}
} else {
break;
}
}
if (pos < lineStartPosn) {
- return false; //XXX not quite right if the prev line is a continuation
+ return false;
}
// First things where the action is unambiguous
switch (style) {
@@ -1490,7 +1542,7 @@ static bool keywordIsModifier(const char *word,
// Assume that if the keyword follows an operator,
// usually it's a block assignment, like
// a << if x then y else z
-
+
ch = styler[pos];
switch (ch) {
case ')':
@@ -1561,25 +1613,25 @@ static bool keywordDoStartsLoop(int pos,
/*
* Folding Ruby
- *
+ *
* The language is quite complex to analyze without a full parse.
* For example, this line shouldn't affect fold level:
- *
+ *
* print "hello" if feeling_friendly?
- *
+ *
* Neither should this:
- *
+ *
* print "hello" \
* if feeling_friendly?
- *
- *
+ *
+ *
* But this should:
- *
+ *
* if feeling_friendly? #++
* print "hello" \
* print "goodbye"
* end #--
- *
+ *
* So we cheat, by actually looking at the existing indentation
* levels for each line, and just echoing it back. Like Python.
* Then if we get better at it, we'll take braces into consideration,
@@ -1587,29 +1639,29 @@ static bool keywordDoStartsLoop(int pos,
* How the keywords should work:
* No effect:
- * __FILE__ __LINE__ BEGIN END alias and
+ * __FILE__ __LINE__ BEGIN END alias and
* defined? false in nil not or self super then
* true undef
* Always increment:
* begin class def do for module when {
- *
+ *
* Always decrement:
* end }
- *
+ *
* Increment if these start a statement
* if unless until while -- do nothing if they're modifiers
* These end a block if there's no modifier, but don't bother
* break next redo retry return yield
- *
+ *
* These temporarily de-indent, but re-indent
* case else elsif ensure rescue
- *
+ *
* This means that the folder reflects indentation rather
* than setting it. The language-service updates indentation
* when users type return and finishes entering de-denters.
- *
+ *
* Later offer to fold POD, here-docs, strings, and blocks of comments
*/
@@ -1617,7 +1669,7 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
WordList *[], Accessor &styler) {
const bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
-
+
synchronizeDocStart(startPos, length, initStyle, styler, // ref args
false);
unsigned int endPos = startPos + length;
@@ -1676,7 +1728,13 @@ static void FoldRbDoc(unsigned int startPos, int length, int initStyle,
) {
levelCurrent++;
}
- }
+ } else if (style == SCE_RB_HERE_DELIM) {
+ if (styler.SafeGetCharAt(i-2) == '<' && styler.SafeGetCharAt(i-1) == '<') {
+ levelCurrent++;
+ } else if (styleNext == SCE_RB_DEFAULT) {
+ levelCurrent--;
+ }
+ }
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
@@ -1712,4 +1770,4 @@ static const char * const rubyWordListDesc[] = {
0
};
-LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc);
+LexerModule lmRuby(SCLEX_RUBY, ColouriseRbDoc, "ruby", FoldRbDoc, rubyWordListDesc, 6);
diff --git a/plugins/scintilla/scintilla/LexSML.cxx b/plugins/scintilla/scintilla/LexSML.cxx
index a617530..6ab902d 100644
--- a/plugins/scintilla/scintilla/LexSML.cxx
+++ b/plugins/scintilla/scintilla/LexSML.cxx
@@ -6,21 +6,23 @@
// Modified from LexCaml.cxx by Robert Roessler <robertr rftp com> Copyright 2005
// The License.txt file describes the conditions under which this software may be distributed.
-
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
inline int issml(int c) {return isalnum(c) || c == '_';}
inline int issmlf(int c) {return isalpha(c) || c == '_';}
@@ -67,7 +69,7 @@ void ColouriseSMLDoc(
else if (sc.Match('#','\"')){
state2 = SCE_SML_CHAR,chLit = 0;
sc.Forward();
-
+
}
else if (isdigit(sc.ch)) {
state2 = SCE_SML_NUMBER, chBase = 10;
@@ -203,13 +205,11 @@ void ColouriseSMLDoc(
}
void FoldSMLDoc(
- unsigned int startPos, int length,
- int initStyle,
- WordList *keywordlists[],
- Accessor &styler)
+ unsigned int, int,
+ int,
+ WordList *[],
+ Accessor &)
{
- //supress "not used" warnings
- startPos || length || initStyle || keywordlists[0] || styler.Length();
}
static const char * const SMLWordListDesc[] = {
@@ -220,4 +220,4 @@ static const char * const SMLWordListDesc[] = {
};
LexerModule lmSML(SCLEX_SML, ColouriseSMLDoc, "SML", FoldSMLDoc, SMLWordListDesc);
-
+
diff --git a/plugins/scintilla/scintilla/LexSQL.cxx b/plugins/scintilla/scintilla/LexSQL.cxx
index 7a4335b..64a896e 100644
--- a/plugins/scintilla/scintilla/LexSQL.cxx
+++ b/plugins/scintilla/scintilla/LexSQL.cxx
@@ -2,30 +2,46 @@
/** @file LexSQL.cxx
** Lexer for SQL, including PL/SQL and SQL*Plus.
**/
-// Copyright 1998-2005 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#ifdef _MSC_VER
+#pragma warning(disable: 4786)
+#endif
-#include "PropSet.h"
-#include "Accessor.h"
-#include "StyleContext.h"
-#include "KeyWords.h"
+#include <string>
+#include <vector>
+#include <map>
+#include <algorithm>
+
+#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"
+#include "OptionSet.h"
+
#ifdef SCI_NAMESPACE
using namespace Scintilla;
#endif
-static inline bool IsAWordChar(int ch) {
- return (ch < 0x80) && (isalnum(ch) || ch == '_');
+static inline bool IsAWordChar(int ch, bool sqlAllowDottedWord) {
+ if (!sqlAllowDottedWord)
+ return (ch < 0x80) && (isalnum(ch) || ch == '_');
+ else
+ return (ch < 0x80) && (isalnum(ch) || ch == '_' || ch == '.');
}
static inline bool IsAWordStart(int ch) {
@@ -43,31 +59,303 @@ static inline bool IsANumberChar(int ch) {
// Not exactly following number definition (several dots are seen as OK, etc.)
// but probably enough in most cases.
return (ch < 0x80) &&
- (isdigit(ch) || toupper(ch) == 'E' ||
- ch == '.' || ch == '-' || ch == '+');
+ (isdigit(ch) || toupper(ch) == 'E' ||
+ ch == '.' || ch == '-' || ch == '+');
}
-static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler) {
- WordList &keywords1 = *keywordlists[0];
- WordList &keywords2 = *keywordlists[1];
- WordList &kw_pldoc = *keywordlists[2];
- WordList &kw_sqlplus = *keywordlists[3];
- WordList &kw_user1 = *keywordlists[4];
- WordList &kw_user2 = *keywordlists[5];
- WordList &kw_user3 = *keywordlists[6];
- WordList &kw_user4 = *keywordlists[7];
+class SQLStates {
+public :
+ void Set(int lineNumber, unsigned short int sqlStatesLine) {
+ if (!sqlStatement.size() == 0 || !sqlStatesLine == 0) {
+ sqlStatement.resize(lineNumber + 1, 0);
+ sqlStatement[lineNumber] = sqlStatesLine;
+ }
+ }
- StyleContext sc(startPos, length, initStyle, styler);
+ unsigned short int IgnoreWhen (unsigned short int sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_IGNORE_WHEN;
+ else
+ sqlStatesLine &= ~MASK_IGNORE_WHEN;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int IntoCondition (unsigned short int sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_INTO_CONDITION;
+ else
+ sqlStatesLine &= ~MASK_INTO_CONDITION;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int IntoExceptionBlock (unsigned short int sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_INTO_EXCEPTION;
+ else
+ sqlStatesLine &= ~MASK_INTO_EXCEPTION;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int IntoDeclareBlock (unsigned short int sqlStatesLine, bool enable) {
+ if (enable)
+ sqlStatesLine |= MASK_INTO_DECLARE;
+ else
+ sqlStatesLine &= ~MASK_INTO_DECLARE;
+
+ return sqlStatesLine;
+ }
+
+ unsigned short int BeginCaseBlock (unsigned short int sqlStatesLine) {
+ if ((sqlStatesLine & MASK_NESTED_CASES) < MASK_NESTED_CASES) {
+ sqlStatesLine++;
+ }
+ return sqlStatesLine;
+ }
+
+ unsigned short int EndCaseBlock (unsigned short int sqlStatesLine) {
+ if ((sqlStatesLine & MASK_NESTED_CASES) > 0) {
+ sqlStatesLine--;
+ }
+ return sqlStatesLine;
+ }
+
+ bool IsIgnoreWhen (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_IGNORE_WHEN) != 0;
+ }
+
+ bool IsIntoCondition (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_CONDITION) != 0;
+ }
+
+ bool IsIntoCaseBlock (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_NESTED_CASES) != 0;
+ }
+
+ bool IsIntoExceptionBlock (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;
+ }
+
+ bool IsIntoDeclareBlock (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_DECLARE) != 0;
+ }
+
+ unsigned short int ForLine(int lineNumber) {
+ if ((lineNumber > 0) && (sqlStatement.size() > static_cast<size_t>(lineNumber))) {
+ return sqlStatement[lineNumber];
+ } else {
+ return 0;
+ }
+ }
+
+ SQLStates() {}
+
+private :
+ std::vector <unsigned short int> sqlStatement;
+ enum {
+ MASK_INTO_DECLARE = 0x1000,
+ MASK_INTO_EXCEPTION = 0x2000,
+ MASK_INTO_CONDITION = 0x4000,
+ MASK_IGNORE_WHEN = 0x8000,
+ MASK_NESTED_CASES = 0x0FFF
+ };
+};
+
+// Options used for LexerSQL
+struct OptionsSQL {
+ bool fold;
+ bool foldAtElse;
+ bool foldComment;
+ bool foldCompact;
+ bool foldOnlyBegin;
+ bool sqlBackticksIdentifier;
+ bool sqlNumbersignComment;
+ bool sqlBackslashEscapes;
+ bool sqlAllowDottedWord;
+ OptionsSQL() {
+ fold = false;
+ foldAtElse = false;
+ foldComment = false;
+ foldCompact = false;
+ foldOnlyBegin = false;
+ sqlBackticksIdentifier = false;
+ sqlNumbersignComment = false;
+ sqlBackslashEscapes = false;
+ sqlAllowDottedWord = false;
+ }
+};
+
+static const char * const sqlWordListDesc[] = {
+ "Keywords",
+ "Database Objects",
+ "PLDoc",
+ "SQL*Plus",
+ "User Keywords 1",
+ "User Keywords 2",
+ "User Keywords 3",
+ "User Keywords 4",
+ 0
+};
+
+struct OptionSetSQL : public OptionSet<OptionsSQL> {
+ OptionSetSQL() {
+ DefineProperty("fold", &OptionsSQL::fold);
+
+ DefineProperty("fold.sql.at.else", &OptionsSQL::foldAtElse,
+ "This option enables SQL folding on a \"ELSE\" and \"ELSIF\" line of an IF statement.");
+
+ DefineProperty("fold.comment", &OptionsSQL::foldComment);
+
+ DefineProperty("fold.compact", &OptionsSQL::foldCompact);
+
+ DefineProperty("fold.sql.only.begin", &OptionsSQL::foldOnlyBegin);
+
+ DefineProperty("lexer.sql.backticks.identifier", &OptionsSQL::sqlBackticksIdentifier);
+
+ DefineProperty("lexer.sql.numbersign.comment", &OptionsSQL::sqlNumbersignComment,
+ "If \"lexer.sql.numbersign.comment\" property is set to 0 a line beginning with '#' will not be a comment.");
+
+ DefineProperty("sql.backslash.escapes", &OptionsSQL::sqlBackslashEscapes,
+ "Enables backslash as an escape character in SQL.");
+
+ DefineProperty("lexer.sql.allow.dotted.word", &OptionsSQL::sqlAllowDottedWord,
+ "Set to 1 to colourise recognized words with dots "
+ "(recommended for Oracle PL/SQL objects).");
+
+ DefineWordListSets(sqlWordListDesc);
+ }
+};
+
+class LexerSQL : public ILexer {
+public :
+ LexerSQL() {}
+
+ int SCI_METHOD Version () const {
+ return lvOriginal;
+ }
+
+ void SCI_METHOD Release() {
+ delete this;
+ }
+
+ const char * SCI_METHOD PropertyNames() {
+ return osSQL.PropertyNames();
+ }
- // property sql.backslash.escapes
- // Enables backslash as an escape character in SQL.
- bool sqlBackslashEscapes = styler.GetPropertyInt("sql.backslash.escapes", 0) != 0;
+ int SCI_METHOD PropertyType(const char *name) {
+ return osSQL.PropertyType(name);
+ }
+
+ const char * SCI_METHOD DescribeProperty(const char *name) {
+ return osSQL.DescribeProperty(name);
+ }
+
+ int SCI_METHOD PropertySet(const char *key, const char *val) {
+ if (osSQL.PropertySet(&options, key, val)) {
+ return 0;
+ }
+ return -1;
+ }
+
+ const char * SCI_METHOD DescribeWordListSets() {
+ return osSQL.DescribeWordListSets();
+ }
+
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex (unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+
+ void * SCI_METHOD PrivateCall(int, void *) {
+ return 0;
+ }
+
+ static ILexer *LexerFactorySQL() {
+ return new LexerSQL();
+ }
+private:
+ bool IsStreamCommentStyle(int style) {
+ return style == SCE_SQL_COMMENT ||
+ style == SCE_SQL_COMMENTDOC ||
+ style == SCE_SQL_COMMENTDOCKEYWORD ||
+ style == SCE_SQL_COMMENTDOCKEYWORDERROR;
+ }
- bool sqlBackticksIdentifier = styler.GetPropertyInt("lexer.sql.backticks.identifier", 0) != 0;
+ bool IsCommentStyle (int style) {
+ switch (style) {
+ case SCE_SQL_COMMENT :
+ case SCE_SQL_COMMENTDOC :
+ case SCE_SQL_COMMENTLINE :
+ case SCE_SQL_COMMENTLINEDOC :
+ case SCE_SQL_COMMENTDOCKEYWORD :
+ case SCE_SQL_COMMENTDOCKEYWORDERROR :
+ return true;
+ default :
+ return false;
+ }
+ }
+
+ OptionsSQL options;
+ OptionSetSQL osSQL;
+ SQLStates sqlStates;
+
+ WordList keywords1;
+ WordList keywords2;
+ WordList kw_pldoc;
+ WordList kw_sqlplus;
+ WordList kw_user1;
+ WordList kw_user2;
+ WordList kw_user3;
+ WordList kw_user4;
+};
+
+int SCI_METHOD LexerSQL::WordListSet(int n, const char *wl) {
+ WordList *wordListN = 0;
+ switch (n) {
+ case 0:
+ wordListN = &keywords1;
+ break;
+ case 1:
+ wordListN = &keywords2;
+ break;
+ case 2:
+ wordListN = &kw_pldoc;
+ break;
+ case 3:
+ wordListN = &kw_sqlplus;
+ break;
+ case 4:
+ wordListN = &kw_user1;
+ break;
+ case 5:
+ wordListN = &kw_user2;
+ break;
+ case 6:
+ wordListN = &kw_user3;
+ break;
+ case 7:
+ wordListN = &kw_user4;
+ }
+ int firstModification = -1;
+ if (wordListN) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*wordListN != wlNew) {
+ wordListN->Set(wl);
+ firstModification = 0;
+ }
+ }
+ return firstModification;
+}
+
+void SCI_METHOD LexerSQL::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ LexAccessor styler(pAccess);
+ StyleContext sc(startPos, length, initStyle, styler);
int styleBeforeDCKeyword = SCE_SQL_DEFAULT;
- for (; sc.More(); sc.Forward()) {
+ int offset = 0;
+ for (; sc.More(); sc.Forward(), offset++) {
// Determine if the current state should terminate.
switch (sc.state) {
case SCE_SQL_OPERATOR:
@@ -80,7 +368,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
}
break;
case SCE_SQL_IDENTIFIER:
- if (!IsAWordChar(sc.ch)) {
+ if (!IsAWordChar(sc.ch, options.sqlAllowDottedWord)) {
int nextState = SCE_SQL_DEFAULT;
char s[1000];
sc.GetCurrentLowered(s, sizeof(s));
@@ -157,7 +445,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
}
break;
case SCE_SQL_CHARACTER:
- if (sqlBackslashEscapes && sc.ch == '\\') {
+ if (options.sqlBackslashEscapes && sc.ch == '\\') {
sc.Forward();
} else if (sc.ch == '\'') {
if (sc.chNext == '\"') {
@@ -187,7 +475,7 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
sc.SetState(SCE_SQL_NUMBER);
} else if (IsAWordStart(sc.ch)) {
sc.SetState(SCE_SQL_IDENTIFIER);
- } else if (sc.ch == 0x60 && sqlBackticksIdentifier) {
+ } else if (sc.ch == 0x60 && options.sqlBackticksIdentifier) {
sc.SetState(SCE_SQL_QUOTEDIDENTIFIER);
} else if (sc.Match('/', '*')) {
if (sc.Match("/**") || sc.Match("/*!")) { // Support of Doxygen doc. style
@@ -200,9 +488,9 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
// MySQL requires a space or control char after --
// http://dev.mysql.com/doc/mysql/en/ansi-diff-comments.html
// Perhaps we should enforce that with proper property:
-//~ } else if (sc.Match("-- ")) {
+ //~ } else if (sc.Match("-- ")) {
sc.SetState(SCE_SQL_COMMENTLINE);
- } else if (sc.ch == '#') {
+ } else if (sc.ch == '#' && options.sqlNumbersignComment) {
sc.SetState(SCE_SQL_COMMENTLINEDOC);
} else if (sc.ch == '\'') {
sc.SetState(SCE_SQL_CHARACTER);
@@ -216,25 +504,10 @@ static void ColouriseSQLDoc(unsigned int startPos, int length, int initStyle, Wo
sc.Complete();
}
-static bool IsStreamCommentStyle(int style) {
- return style == SCE_SQL_COMMENT ||
- style == SCE_SQL_COMMENTDOC ||
- style == SCE_SQL_COMMENTDOCKEYWORD ||
- style == SCE_SQL_COMMENTDOCKEYWORDERROR;
-}
-
-// Store both the current line's fold level and the next lines in the
-// level store to make it easy to pick up with each increment.
-static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
- WordList *[], Accessor &styler) {
- bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
- bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
- bool foldOnlyBegin = styler.GetPropertyInt("fold.sql.only.begin", 0) != 0;
-
- // property fold.sql.exists
- // Enables "EXISTS" to end a fold as is started by "IF" in "DROP TABLE IF EXISTS".
- bool foldSqlExists = styler.GetPropertyInt("fold.sql.exists", 1) != 0;
-
+void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ if (!options.fold)
+ return;
+ LexAccessor styler(pAccess);
unsigned int endPos = startPos + length;
int visibleChars = 0;
int lineCurrent = styler.GetLine(startPos);
@@ -247,6 +520,14 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
int styleNext = styler.StyleAt(startPos);
int style = initStyle;
bool endFound = false;
+ bool isUnfoldingIgnored = false;
+ // this statementFound flag avoids to fold when the statement is on only one line by ignoring ELSE or ELSIF
+ // eg. "IF condition1 THEN ... ELSIF condition2 THEN ... ELSE ... END IF;"
+ bool statementFound = false;
+ unsigned short int sqlStatesCurrentLine = 0;
+ if (!options.foldOnlyBegin) {
+ sqlStatesCurrentLine = sqlStates.ForLine(lineCurrent);
+ }
for (unsigned int i = startPos; i < endPos; i++) {
char ch = chNext;
chNext = styler.SafeGetCharAt(i + 1);
@@ -254,7 +535,16 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && IsStreamCommentStyle(style)) {
+ if (atEOL || (!IsCommentStyle(style) && ch == ';')) {
+ if (endFound) {
+ //Maybe this is the end of "EXCEPTION" BLOCK (eg. "BEGIN ... EXCEPTION ... END;")
+ sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, false);
+ }
+ // set endFound and isUnfoldingIgnored to false if EOL is reached or ';' is found
+ endFound = false;
+ isUnfoldingIgnored = false;
+ }
+ if (options.foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
levelNext++;
} else if (!IsStreamCommentStyle(styleNext) && !atEOL) {
@@ -262,7 +552,7 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
levelNext--;
}
}
- if (foldComment && (style == SCE_SQL_COMMENTLINE)) {
+ if (options.foldComment && (style == SCE_SQL_COMMENTLINE)) {
// MySQL needs -- comments to be followed by space or control char
if ((ch == '-') && (chNext == '-')) {
char chNext2 = styler.SafeGetCharAt(i + 2);
@@ -276,14 +566,18 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
}
if (style == SCE_SQL_OPERATOR) {
if (ch == '(') {
+ if (levelCurrent > levelNext)
+ levelCurrent--;
levelNext++;
} else if (ch == ')') {
levelNext--;
+ } else if ((!options.foldOnlyBegin) && ch == ';') {
+ sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, false);
}
}
// If new keyword (cannot trigger on elseif or nullif, does less tests)
if (style == SCE_SQL_WORD && stylePrev != SCE_SQL_WORD) {
- const int MAX_KW_LEN = 6; // Maximum length of folding keywords
+ const int MAX_KW_LEN = 9; // Maximum length of folding keywords
char s[MAX_KW_LEN + 2];
unsigned int j = 0;
for (; j < MAX_KW_LEN + 1; j++) {
@@ -298,33 +592,133 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
} else {
s[j] = '\0';
}
- if ((!foldOnlyBegin) && (strcmp(s, "if") == 0 || strcmp(s, "loop") == 0)) {
+
+ if (strcmp(s, "if") == 0) {
if (endFound) {
- // ignore
endFound = false;
+ if (options.foldOnlyBegin && !isUnfoldingIgnored) {
+ // this end isn't for begin block, but for if block ("end if;")
+ // so ignore previous "end" by increment levelNext.
+ levelNext++;
+ }
} else {
- levelNext++;
+ if (!options.foldOnlyBegin)
+ sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+ if (levelCurrent > levelNext) {
+ // doesn't include this line into the folding block
+ // because doesn't hide IF (eg "END; IF")
+ levelCurrent = levelNext;
+ }
+ }
+ } else if (!options.foldOnlyBegin &&
+ strcmp(s, "then") == 0 &&
+ sqlStates.IsIntoCondition(sqlStatesCurrentLine)) {
+ sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, false);
+ if (!options.foldOnlyBegin) {
+ if (levelCurrent > levelNext) {
+ levelCurrent = levelNext;
+ }
+ if (!statementFound)
+ levelNext++;
+
+ statementFound = true;
+ } else if (levelCurrent > levelNext) {
+ // doesn't include this line into the folding block
+ // because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
+ levelCurrent = levelNext;
+ }
+ } else if (strcmp(s, "loop") == 0 ||
+ strcmp(s, "case") == 0) {
+ if (endFound) {
+ endFound = false;
+ if (options.foldOnlyBegin && !isUnfoldingIgnored) {
+ // this end isn't for begin block, but for loop block ("end loop;") or case block ("end case;")
+ // so ignore previous "end" by increment levelNext.
+ levelNext++;
+ }
+ if ((!options.foldOnlyBegin) && strcmp(s, "case") == 0) {
+ sqlStatesCurrentLine = sqlStates.EndCaseBlock(sqlStatesCurrentLine);
+ levelNext--; //again for the "end case;" and block when
+ }
+ } else if (!options.foldOnlyBegin) {
+ if (strcmp(s, "case") == 0) {
+ sqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine);
+
+ //for case block increment 2 times
+ if (!statementFound)
+ levelNext++;
+ }
+
+ if (levelCurrent > levelNext) {
+ levelCurrent = levelNext;
+ }
+ if (!statementFound)
+ levelNext++;
+
+ statementFound = true;
+ } else if (levelCurrent > levelNext) {
+ // doesn't include this line into the folding block
+ // because doesn't hide LOOP or CASE (eg "END; LOOP" or "END; CASE")
+ levelCurrent = levelNext;
}
+ } else if ((!options.foldOnlyBegin) && (
+ // folding for ELSE and ELSIF block only if foldAtElse is set
+ // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
+ options.foldAtElse && !statementFound) && strcmp(s, "elsif") == 0) {
+ sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+ levelCurrent--;
+ levelNext--;
+ } else if ((!options.foldOnlyBegin) && (
+ // folding for ELSE and ELSIF block only if foldAtElse is set
+ // and IF or CASE aren't on only one line with ELSE or ELSIF (with flag statementFound)
+ options.foldAtElse && !statementFound) && strcmp(s, "else") == 0) {
+ // prevent also ELSE is on the same line (eg. "ELSE ... END IF;")
+ statementFound = true;
+ // we are in same case "} ELSE {" in C language
+ levelCurrent--;
+
} else if (strcmp(s, "begin") == 0) {
levelNext++;
+ sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, false);
} else if ((strcmp(s, "end") == 0) ||
-// // DROP TABLE IF EXISTS or CREATE TABLE IF NOT EXISTS
- (foldSqlExists && (strcmp(s, "exists") == 0)) ||
-// // SQL Anywhere permits IF ... ELSE ... ENDIF
-// // will only be active if "endif" appears in the
-// // keyword list.
- (strcmp(s, "endif") == 0)) {
+ // SQL Anywhere permits IF ... ELSE ... ENDIF
+ // will only be active if "endif" appears in the
+ // keyword list.
+ (strcmp(s, "endif") == 0)) {
endFound = true;
levelNext--;
if (levelNext < SC_FOLDLEVELBASE) {
levelNext = SC_FOLDLEVELBASE;
+ isUnfoldingIgnored = true;
+ }
+ } else if ((!options.foldOnlyBegin) &&
+ strcmp(s, "when") == 0 &&
+ !sqlStates.IsIgnoreWhen(sqlStatesCurrentLine) &&
+ !sqlStates.IsIntoExceptionBlock(sqlStatesCurrentLine) &&
+ sqlStates.IsIntoCaseBlock(sqlStatesCurrentLine)) {
+ sqlStatesCurrentLine = sqlStates.IntoCondition(sqlStatesCurrentLine, true);
+
+ // Don't foldind when CASE and WHEN are on the same line (with flag statementFound) (eg. "CASE selector WHEN expression1 THEN sequence_of_statements1;\n")
+ if (!statementFound) {
+ levelCurrent--;
+ levelNext--;
}
+ } else if ((!options.foldOnlyBegin) && strcmp(s, "exit") == 0) {
+ sqlStatesCurrentLine = sqlStates.IgnoreWhen(sqlStatesCurrentLine, true);
+ } else if ((!options.foldOnlyBegin) && !sqlStates.IsIntoDeclareBlock(sqlStatesCurrentLine) && strcmp(s, "exception") == 0) {
+ sqlStatesCurrentLine = sqlStates.IntoExceptionBlock(sqlStatesCurrentLine, true);
+ } else if ((!options.foldOnlyBegin) &&
+ (strcmp(s, "declare") == 0 ||
+ strcmp(s, "function") == 0 ||
+ strcmp(s, "procedure") == 0 ||
+ strcmp(s, "package") == 0)) {
+ sqlStatesCurrentLine = sqlStates.IntoDeclareBlock(sqlStatesCurrentLine, true);
}
}
if (atEOL) {
int levelUse = levelCurrent;
int lev = levelUse | levelNext << 16;
- if (visibleChars == 0 && foldCompact)
+ if (visibleChars == 0 && options.foldCompact)
lev |= SC_FOLDLEVELWHITEFLAG;
if (levelUse < levelNext)
lev |= SC_FOLDLEVELHEADERFLAG;
@@ -334,7 +728,9 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
lineCurrent++;
levelCurrent = levelNext;
visibleChars = 0;
- endFound = false;
+ statementFound = false;
+ if (!options.foldOnlyBegin)
+ sqlStates.Set(lineCurrent, sqlStatesCurrentLine);
}
if (!isspacechar(ch)) {
visibleChars++;
@@ -342,16 +738,4 @@ static void FoldSQLDoc(unsigned int startPos, int length, int initStyle,
}
}
-static const char * const sqlWordListDesc[] = {
- "Keywords",
- "Database Objects",
- "PLDoc",
- "SQL*Plus",
- "User Keywords 1",
- "User Keywords 2",
- "User Keywords 3",
- "User Keywords 4",
- 0
-};
-
-LexerModule lmSQL(SCLEX_SQL, ColouriseSQLDoc, "sql", FoldSQLDoc, sqlWordListDesc);
+LexerModule lmSQL(SCLEX_SQL, LexerSQL::LexerFactorySQL, "sql", sqlWordListDesc);
diff --git a/plugins/scintilla/scintilla/LexScriptol.cxx b/plugins/scintilla/scintilla/LexScriptol.cxx
index 76c38e6..17184fc 100644
--- a/plugins/scintilla/scintilla/LexScriptol.cxx
+++ b/plugins/scintilla/scintilla/LexScriptol.cxx
@@ -5,18 +5,22 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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
@@ -48,10 +52,9 @@ static void ClassifyWordSol(unsigned int start, unsigned int end, WordList &keyw
static bool IsSolComment(Accessor &styler, int pos, int len)
{
- char c;
if(len > 0)
{
- c = styler[pos];
+ char c = styler[pos];
if(c == '`') return true;
if(len > 1)
{
@@ -328,7 +331,7 @@ static void ColouriseSolDoc(unsigned int startPos, int length, int initStyle,
state = SCE_SCRIPTOL_DEFAULT;
}
}
-
+
}
chPrev2 = chPrev;
chPrev = ch;
diff --git a/plugins/scintilla/scintilla/LexSmalltalk.cxx b/plugins/scintilla/scintilla/LexSmalltalk.cxx
index 265de38..7c7c067 100644
--- a/plugins/scintilla/scintilla/LexSmalltalk.cxx
+++ b/plugins/scintilla/scintilla/LexSmalltalk.cxx
@@ -8,16 +8,21 @@
#include <stdlib.h>
#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -39,7 +44,7 @@ classificationBlock
value: #BinSel value: '~ %&*-+=|\/,<>?!';
value: #Upper value: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'.
-((String new: 500) streamContents: [ :stream |
+((String new: 500) streamContents: [ :stream |
stream crLf; nextPutAll: 'static int ClassificationTable[256] = {'.
lexTable keysAndValuesDo: [ :index :value |
((index - 1) rem: 16) == 0 ifTrue: [
@@ -50,7 +55,7 @@ classificationBlock
index ~= 256 ifTrue: [
stream nextPut: $,]].
stream crLf; nextPutAll: '};'; crLf.
-
+
charClasses keysAndValuesDo: [ :index :name |
stream
crLf;
@@ -95,7 +100,7 @@ static inline bool isDigitOfRadix(int ch, int radix)
}
static inline void skipComment(StyleContext& sc)
-{
+{
while (sc.More() && sc.ch != '\"')
sc.Forward();
}
@@ -118,7 +123,7 @@ static void handleHash(StyleContext& sc)
sc.SetState(SCE_ST_SPECIAL);
return;
}
-
+
sc.SetState(SCE_ST_SYMBOL);
sc.Forward();
if (sc.ch == '\'') {
@@ -162,7 +167,7 @@ static void handleNumeric(StyleContext& sc)
char num[256];
int nl;
int radix;
-
+
sc.SetState(SCE_ST_NUMBER);
num[0] = static_cast<char>(sc.ch);
nl = 1;
@@ -217,7 +222,7 @@ static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
int il;
int state;
bool doubleColonPresent;
-
+
sc.SetState(SCE_ST_DEFAULT);
ident[0] = static_cast<char>(sc.ch);
@@ -237,7 +242,7 @@ static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
else
doubleColonPresent = false;
ident[il] = 0;
-
+
if (specialSelectorList->InList(ident))
state = SCE_ST_SPEC_SEL;
else if (doubleColonPresent)
@@ -256,7 +261,7 @@ static void handleLetter(StyleContext& sc, WordList* specialSelectorList)
else
state = SCE_ST_DEFAULT;
}
-
+
sc.ChangeState(state);
}
@@ -277,7 +282,7 @@ static void colorizeSmalltalkDoc(unsigned int startPos, int length, int initStyl
for (; sc.More(); sc.Forward()) {
int ch;
-
+
ch = sc.ch;
if (ch == '\"') {
sc.SetState(SCE_ST_COMMENT);
diff --git a/plugins/scintilla/scintilla/LexSorcus.cxx b/plugins/scintilla/scintilla/LexSorcus.cxx
index 1d8ba27..ba5588b 100644
--- a/plugins/scintilla/scintilla/LexSorcus.cxx
+++ b/plugins/scintilla/scintilla/LexSorcus.cxx
@@ -9,18 +9,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -29,7 +32,7 @@ using namespace Scintilla;
//each character a..z and A..Z + '_' can be part of a keyword
//additionally numbers that follow 'M' can be contained in a keyword
-static inline bool IsSWordStart(const int ch, const int prev_ch)
+static inline bool IsSWordStart(const int ch, const int prev_ch)
{
if (isalpha(ch) || (ch == '_') || ((isdigit(ch)) && (prev_ch == 'M')))
return true;
@@ -39,7 +42,7 @@ static inline bool IsSWordStart(const int ch, const int prev_ch)
//only digits that are not preceded by 'M' count as a number
-static inline bool IsSorcusNumber(const int ch, const int prev_ch)
+static inline bool IsSorcusNumber(const int ch, const int prev_ch)
{
if ((isdigit(ch)) && (prev_ch != 'M'))
return true;
@@ -49,46 +52,46 @@ static inline bool IsSorcusNumber(const int ch, const int prev_ch)
//only = is a valid operator
-static inline bool IsSorcusOperator(const int ch)
+static inline bool IsSorcusOperator(const int ch)
{
if (ch == '=')
return true;
-
+
return false;
}
static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle, WordList *keywordlists[],
- Accessor &styler)
+ Accessor &styler)
{
-
+
WordList &Command = *keywordlists[0];
WordList &Parameter = *keywordlists[1];
WordList &Constant = *keywordlists[2];
-
+
// Do not leak onto next line
- if (initStyle == SCE_SORCUS_STRINGEOL)
+ if (initStyle == SCE_SORCUS_STRINGEOL)
initStyle = SCE_SORCUS_DEFAULT;
-
+
StyleContext sc(startPos, length, initStyle, styler);
-
+
for (; sc.More(); sc.Forward())
{
-
+
// Prevent SCE_SORCUS_STRINGEOL from leaking back to previous line
if (sc.atLineStart && (sc.state == SCE_SORCUS_STRING))
{
- sc.SetState(SCE_SORCUS_STRING);
- }
-
+ sc.SetState(SCE_SORCUS_STRING);
+ }
+
// Determine if the current state should terminate.
if (sc.state == SCE_SORCUS_OPERATOR)
{
- if (!IsSorcusOperator(sc.ch))
+ if (!IsSorcusOperator(sc.ch))
{
sc.SetState(SCE_SORCUS_DEFAULT);
}
- }
+ }
else if(sc.state == SCE_SORCUS_NUMBER)
{
if(!IsSorcusNumber(sc.ch, sc.chPrev))
@@ -101,25 +104,25 @@ static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle,
if (!IsSWordStart(sc.ch, sc.chPrev))
{
char s[100];
-
+
sc.GetCurrent(s, sizeof(s));
-
+
if (Command.InList(s))
- {
- sc.ChangeState(SCE_SORCUS_COMMAND);
+ {
+ sc.ChangeState(SCE_SORCUS_COMMAND);
}
else if (Parameter.InList(s))
- {
+ {
sc.ChangeState(SCE_SORCUS_PARAMETER);
}
else if (Constant.InList(s))
- {
+ {
sc.ChangeState(SCE_SORCUS_CONSTANT);
}
-
+
sc.SetState(SCE_SORCUS_DEFAULT);
}
- }
+ }
else if (sc.state == SCE_SORCUS_COMMENTLINE )
{
if (sc.atLineEnd)
@@ -133,24 +136,24 @@ static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle,
{
sc.ForwardSetState(SCE_SORCUS_DEFAULT);
}
- else if (sc.atLineEnd)
+ else if (sc.atLineEnd)
{
sc.ChangeState(SCE_SORCUS_STRINGEOL);
sc.ForwardSetState(SCE_SORCUS_DEFAULT);
}
}
-
+
// Determine if a new state should be entered.
if (sc.state == SCE_SORCUS_DEFAULT)
{
if ((sc.ch == ';') || (sc.ch == '\''))
{
sc.SetState(SCE_SORCUS_COMMENTLINE);
- }
+ }
else if (IsSWordStart(sc.ch, sc.chPrev))
{
sc.SetState(SCE_SORCUS_IDENTIFIER);
- }
+ }
else if (sc.ch == '\"')
{
sc.SetState(SCE_SORCUS_STRING);
@@ -164,42 +167,42 @@ static void ColouriseSorcusDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_SORCUS_NUMBER);
}
}
-
+
}
sc.Complete();
}
static const char* const SorcusWordListDesc[] = {"Command","Parameter", "Constant", 0};
-
+
LexerModule lmSorc(SCLEX_SORCUS, ColouriseSorcusDoc, "sorcins", 0, SorcusWordListDesc);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/plugins/scintilla/scintilla/LexSpecman.cxx b/plugins/scintilla/scintilla/LexSpecman.cxx
index 093efae..1b96482 100644
--- a/plugins/scintilla/scintilla/LexSpecman.cxx
+++ b/plugins/scintilla/scintilla/LexSpecman.cxx
@@ -11,15 +11,18 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexSpice.cxx b/plugins/scintilla/scintilla/LexSpice.cxx
index 6aa2e8f..cb1e658 100644
--- a/plugins/scintilla/scintilla/LexSpice.cxx
+++ b/plugins/scintilla/scintilla/LexSpice.cxx
@@ -6,19 +6,23 @@
// The License.txt file describes the conditions under which this software may be distributed.
#include <stdlib.h>
-#include <ctype.h>
#include <string.h>
#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
#include <string>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "PropSet.h"
-#include "KeyWords.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexTACL.cxx b/plugins/scintilla/scintilla/LexTACL.cxx
index b0c1244..fb7d695 100644
--- a/plugins/scintilla/scintilla/LexTACL.cxx
+++ b/plugins/scintilla/scintilla/LexTACL.cxx
@@ -10,18 +10,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
diff --git a/plugins/scintilla/scintilla/LexTADS3.cxx b/plugins/scintilla/scintilla/LexTADS3.cxx
index ee16a0a..a180544 100644
--- a/plugins/scintilla/scintilla/LexTADS3.cxx
+++ b/plugins/scintilla/scintilla/LexTADS3.cxx
@@ -33,18 +33,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -70,7 +73,7 @@ static inline bool IsEOL(const int ch, const int chNext) {
* - it doesn't want to admit that there's a newline until reaching the END
* of the sequence. We meet both needs by saying that there's a newline
* when we see the CR in a CR-LF, but skipping the CR before returning so
- * that the caller's caller will see that we've stopped at the LF.
+ * that the caller's caller will see that we've stopped at the LF.
*/
static inline bool IsEOLSkip(StyleContext &sc)
{
@@ -82,17 +85,13 @@ static inline bool IsEOLSkip(StyleContext &sc)
return true;
}
- /*
+ /*
* in other cases, we have at most a 1-character newline, so do the
- * normal IsEOL test
+ * normal IsEOL test
*/
return IsEOL(sc.ch, sc.chNext);
}
-static inline bool IsASpaceOrTab(const int ch) {
- return ch == ' ' || ch == '\t';
-}
-
static inline bool IsATADS3Operator(const int ch) {
return ch == '=' || ch == '{' || ch == '}' || ch == '(' || ch == ')'
|| ch == '[' || ch == ']' || ch == ',' || ch == ':' || ch == ';'
@@ -156,7 +155,7 @@ static void ColouriseTADSHTMLString(StyleContext &sc, int &lineState) {
sc.Forward();
}
if (chQuote == '"')
- lineState &= ~T3_HTML_SQUOTE;
+ lineState &= ~T3_HTML_SQUOTE;
else
lineState |= T3_HTML_SQUOTE;
diff --git a/plugins/scintilla/scintilla/LexTAL.cxx b/plugins/scintilla/scintilla/LexTAL.cxx
index a76a296..15dc741 100644
--- a/plugins/scintilla/scintilla/LexTAL.cxx
+++ b/plugins/scintilla/scintilla/LexTAL.cxx
@@ -10,18 +10,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
@@ -94,7 +97,7 @@ static int classifyWordTAL(unsigned int start, unsigned int end, /*WordList &key
else if (strcmp(s, "end") == 0) {
ret = -1;
}
- }
+ }
else if (s[0] == '$' || builtins.InList(s)) {
chAttr = SCE_C_WORD2;
}
diff --git a/plugins/scintilla/scintilla/LexTCL.cxx b/plugins/scintilla/scintilla/LexTCL.cxx
index 3c175de..de309f2 100644
--- a/plugins/scintilla/scintilla/LexTCL.cxx
+++ b/plugins/scintilla/scintilla/LexTCL.cxx
@@ -7,18 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
-#include <stdarg.h>
#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -47,7 +50,7 @@ static void ColouriseTCLDoc(unsigned int startPos, int length, int , WordList *k
bool foldComment = styler.GetPropertyInt("fold.comment") != 0;
bool commentLevel = false;
bool subBrace = false; // substitution begin with a brace ${.....}
- enum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_COMMENT_BOX, LS_MASK_STATE = 0xf,
+ enum tLineState {LS_DEFAULT, LS_OPEN_COMMENT, LS_OPEN_DOUBLE_QUOTE, LS_COMMENT_BOX, LS_MASK_STATE = 0xf,
LS_COMMAND_EXPECTED = 16, LS_BRACE_ONLY = 32 } lineState = LS_DEFAULT;
bool prevSlash = false;
int currentLevel = 0;
@@ -86,7 +89,7 @@ static void ColouriseTCLDoc(unsigned int startPos, int length, int , WordList *k
StyleContext sc(startPos, length, SCE_TCL_DEFAULT, styler);
for (; ; sc.Forward()) {
next:
- if (sc.ch=='\r' && sc.chNext == '\n') // only ignore \r on PC process on the mac
+ if (sc.ch=='\r' && sc.chNext == '\n') // only ignore \r on PC process on the mac
continue;
bool atEnd = !sc.More(); // make sure we coloured the last word
if (lineState != LS_DEFAULT) {
@@ -170,7 +173,7 @@ next:
sc.ChangeState(SCE_TCL_WORD7);
} else if (keywords9.InList(s)) {
sc.ChangeState(SCE_TCL_WORD8);
- }
+ }
}
expected = false;
sc.SetState(quote ? SCE_TCL_IN_QUOTE : SCE_TCL_DEFAULT);
@@ -212,7 +215,7 @@ next:
} else if (sc.state == SCE_TCL_COMMENT_BOX)
lineState = LS_COMMENT_BOX;
}
- styler.SetLineState(currentLine,
+ styler.SetLineState(currentLine,
(subBrace ? LS_BRACE_ONLY : 0) |
(expected ? LS_COMMAND_EXPECTED : 0) | lineState);
if (lineState == LS_COMMENT_BOX)
@@ -285,7 +288,7 @@ next:
if (sc.ch == '\\') {
prevSlash = true;
- continue;
+ continue;
}
// Determine if a new state should be entered.
@@ -322,7 +325,7 @@ next:
subParen = 0;
if (sc.chNext != '{') {
sc.SetState(SCE_TCL_SUBSTITUTION);
- }
+ }
else {
sc.SetState(SCE_TCL_OPERATOR); // $
sc.Forward(); // {
diff --git a/plugins/scintilla/scintilla/LexTeX.cxx b/plugins/scintilla/scintilla/LexTeX.cxx
index 62ade1d..7b79670 100644
--- a/plugins/scintilla/scintilla/LexTeX.cxx
+++ b/plugins/scintilla/scintilla/LexTeX.cxx
@@ -18,18 +18,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
-
-#include "PropSet.h"
-#include "Accessor.h"
-#include "KeyWords.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;
@@ -285,8 +288,8 @@ static void ColouriseTeXDoc(
static inline bool isNumber(int ch) {
return
- (ch == '0') || (ch == '1') || (ch == '2') ||
- (ch == '3') || (ch == '4') || (ch == '5') ||
+ (ch == '0') || (ch == '1') || (ch == '2') ||
+ (ch == '3') || (ch == '4') || (ch == '5') ||
(ch == '6') || (ch == '7') || (ch == '8') || (ch == '9');
}
@@ -298,7 +301,7 @@ static int ParseTeXCommand(unsigned int pos, Accessor &styler, char *command)
{
int length=0;
char ch=styler.SafeGetCharAt(pos+1);
-
+
if(ch==',' || ch==':' || ch==';' || ch=='%'){
command[0]=ch;
command[1]=0;
@@ -311,14 +314,14 @@ static int ParseTeXCommand(unsigned int pos, Accessor &styler, char *command)
length++;
ch=styler.SafeGetCharAt(pos+length+1);
}
-
- command[length]='\0';
+
+ command[length]='\0';
if(!length) return 0;
return length+1;
}
static int classifyFoldPointTeXPaired(const char* s) {
- int lev=0;
+ int lev=0;
if (!(isdigit(s[0]) || (s[0] == '.'))){
if (strcmp(s, "begin")==0||strcmp(s,"FoldStart")==0||
strcmp(s,"abstract")==0||strcmp(s,"unprotect")==0||
@@ -330,14 +333,14 @@ static int classifyFoldPointTeXPaired(const char* s) {
strcmp(s,"maketitle")==0||strcmp(s,"protect")==0||
strncmp(s,"stop",4)==0||strncmp(s,"Stop",4)==0||
strcmp(s,"fi")==0
- )
+ )
lev=-1;
}
return lev;
}
static int classifyFoldPointTeXUnpaired(const char* s) {
- int lev=0;
+ int lev=0;
if (!(isdigit(s[0]) || (s[0] == '.'))){
if (strcmp(s,"part")==0||
strcmp(s,"chapter")==0||
@@ -362,7 +365,7 @@ static int classifyFoldPointTeXUnpaired(const char* s) {
static bool IsTeXCommentLine(int line, Accessor &styler) {
int pos = styler.LineStart(line);
int eol_pos = styler.LineStart(line + 1) - 1;
-
+
int startpos = pos;
while (startpos<eol_pos){
@@ -370,14 +373,14 @@ static bool IsTeXCommentLine(int line, Accessor &styler) {
if (ch!='%' && ch!=' ') return false;
else if (ch=='%') return true;
startpos++;
- }
+ }
return false;
}
// FoldTeXDoc: borrowed from VisualTeX with modifications
-static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
+static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler)
{
bool foldCompact = styler.GetPropertyInt("fold.compact", 1) != 0;
unsigned int endPos = startPos+length;
@@ -387,7 +390,7 @@ static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Acc
int levelCurrent=levelPrev;
char chNext=styler[startPos];
char buffer[100]="";
-
+
for (unsigned int i=startPos; i < endPos; i++) {
char ch=chNext;
chNext=styler.SafeGetCharAt(i+1);
@@ -412,12 +415,12 @@ static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Acc
chNext4=styler.SafeGetCharAt(i+4);
chNext5=styler.SafeGetCharAt(i+5);
- bool atEOfold = (ch == '%') &&
- (chNext == '%') && (chNext2=='}') &&
+ bool atEOfold = (ch == '%') &&
+ (chNext == '%') && (chNext2=='}') &&
(chNext3=='}')&& (chNext4=='-')&& (chNext5=='-');
- bool atBOfold = (ch == '%') &&
- (chNext == '%') && (chNext2=='-') &&
+ bool atBOfold = (ch == '%') &&
+ (chNext == '%') && (chNext2=='-') &&
(chNext3=='-')&& (chNext4=='{')&& (chNext5=='{');
if(atBOfold){
@@ -427,11 +430,11 @@ static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Acc
if(atEOfold){
levelCurrent-=1;
}
-
+
if(ch=='\\' && chNext=='['){
levelCurrent+=1;
}
-
+
if(ch=='\\' && chNext==']'){
levelCurrent-=1;
}
@@ -452,8 +455,8 @@ static void FoldTexDoc(unsigned int startPos, int length, int, WordList *[], Acc
levelCurrent--;
}
-//---------------------------------------------------------------------------------------------
-
+//---------------------------------------------------------------------------------------------
+
if (atEOL) {
int lev = levelPrev;
if (visibleChars == 0 && foldCompact)
diff --git a/plugins/scintilla/scintilla/LexTxt2tags.cxx b/plugins/scintilla/scintilla/LexTxt2tags.cxx
new file mode 100644
index 0000000..8f8e181
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexTxt2tags.cxx
@@ -0,0 +1,480 @@
+/******************************************************************
+ * LexTxt2tags.cxx
+ *
+ * A simple Txt2tags lexer for scintilla.
+ *
+ *
+ * Adapted by Eric Forgeot
+ * Based on the LexMarkdown.cxx by Jon Strait - jstrait moonloop net
+ *
+ * What could be improved:
+ * - Verbatim lines could be like for raw lines : when there is no space between the ``` and the following text, the first letter should be colored so the user would understand there must be a space for a valid tag.
+ * - marks such as bold, italic, strikeout, underline should begin to be highlighted only when they are closed and valid.
+ * - verbatim and raw area should be highlighted too.
+ *
+ * The License.txt file describes the conditions under which this
+ * software may be distributed.
+ *
+ *****************************************************************/
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.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 inline bool IsNewline(const int ch) {
+ return (ch == '\n' || ch == '\r');
+}
+
+// True if can follow ch down to the end with possibly trailing whitespace
+static bool FollowToLineEnd(const int ch, const int state, const unsigned int endPos, StyleContext &sc) {
+ unsigned int i = 0;
+ while (sc.GetRelative(++i) == ch)
+ ;
+ // Skip over whitespace
+ while (IsASpaceOrTab(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+ ++i;
+ if (IsNewline(sc.GetRelative(i)) || sc.currentPos + i == endPos) {
+ sc.Forward(i);
+ sc.ChangeState(state);
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ return true;
+ }
+ else return false;
+}
+
+// Does the previous line have more than spaces and tabs?
+static bool HasPrevLineContent(StyleContext &sc) {
+ int i = 0;
+ // Go back to the previous newline
+ while ((--i + sc.currentPos) && !IsNewline(sc.GetRelative(i)))
+ ;
+ while (--i + sc.currentPos) {
+ if (IsNewline(sc.GetRelative(i)))
+ break;
+ if (!IsASpaceOrTab(sc.GetRelative(i)))
+ return true;
+ }
+ return false;
+}
+
+// Separator line
+static bool IsValidHrule(const unsigned int endPos, StyleContext &sc) {
+ int c, count = 1;
+ unsigned int i = 0;
+ while (++i) {
+ c = sc.GetRelative(i);
+ if (c == sc.ch)
+ ++count;
+ // hit a terminating character
+ else if (!IsASpaceOrTab(c) || sc.currentPos + i == endPos) {
+ // Are we a valid HRULE
+ if ((IsNewline(c) || sc.currentPos + i == endPos) &&
+ count >= 20 && !HasPrevLineContent(sc)) {
+ sc.SetState(SCE_TXT2TAGS_HRULE);
+ sc.Forward(i);
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ return true;
+ }
+ else {
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ return false;
+ }
+ }
+ }
+ return false;
+}
+
+static void ColorizeTxt2tagsDoc(unsigned int startPos, int length, int initStyle,
+ WordList **, Accessor &styler) {
+ unsigned int endPos = startPos + length;
+ int precharCount = 0;
+ // Don't advance on a new loop iteration and retry at the same position.
+ // Useful in the corner case of having to start at the beginning file position
+ // in the default state.
+ bool freezeCursor = false;
+
+ StyleContext sc(startPos, length, initStyle, styler);
+
+ while (sc.More()) {
+ // Skip past escaped characters
+ if (sc.ch == '\\') {
+ sc.Forward();
+ continue;
+ }
+
+ // A blockquotes resets the line semantics
+ if (sc.state == SCE_TXT2TAGS_BLOCKQUOTE){
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ }
+ // An option colors the whole line
+ if (sc.state == SCE_TXT2TAGS_OPTION){
+ FollowToLineEnd('%', SCE_TXT2TAGS_OPTION, endPos, sc);
+ }
+ if (sc.state == SCE_TXT2TAGS_POSTPROC){
+ FollowToLineEnd('%', SCE_TXT2TAGS_POSTPROC, endPos, sc);
+ }
+ if (sc.state == SCE_TXT2TAGS_PREPROC){
+ FollowToLineEnd('%', SCE_TXT2TAGS_PREPROC, endPos, sc);
+ }
+ // A comment colors the whole line
+ if (sc.state == SCE_TXT2TAGS_COMMENT){
+ FollowToLineEnd('%', SCE_TXT2TAGS_COMMENT, endPos, sc);
+ }
+ // Conditional state-based actions
+ if (sc.state == SCE_TXT2TAGS_CODE2) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("``") && sc.GetRelative(-2) != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Table
+ else if (sc.state == SCE_TXT2TAGS_CODE) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.ch == '|' && sc.chPrev != ' ')
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ // Strong
+ else if (sc.state == SCE_TXT2TAGS_STRONG1) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("**") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Emphasis
+ else if (sc.state == SCE_TXT2TAGS_EM1) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("//") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Underline
+ else if (sc.state == SCE_TXT2TAGS_EM2) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("__") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // codeblock
+ else if (sc.state == SCE_TXT2TAGS_CODEBK) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.atLineStart && sc.Match("```")) {
+ int i = 1;
+ while (!IsNewline(sc.GetRelative(i)) && sc.currentPos + i < endPos)
+ i++;
+ sc.Forward(i);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // strikeout
+ else if (sc.state == SCE_TXT2TAGS_STRIKEOUT) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ if (sc.Match("--") && sc.chPrev != ' ') {
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Headers
+ else if (sc.state == SCE_TXT2TAGS_LINE_BEGIN) {
+ if (sc.Match("======"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER6);
+ sc.Forward();
+ }
+ else if (sc.Match("====="))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER5);
+ sc.Forward();
+ }
+ else if (sc.Match("===="))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER4);
+ sc.Forward();
+ }
+ else if (sc.Match("==="))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER3);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '=', sc);
+ else if (sc.Match("==")) {
+ sc.SetState(SCE_TXT2TAGS_HEADER2);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '=', sc);
+ else if (sc.Match("=")) {
+ // Catch the special case of an unordered list
+ if (sc.chNext == '.' && IsASpaceOrTab(sc.GetRelative(2))) {
+ precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ }
+ else
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER1);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER1, 1, '=', sc);
+ }
+
+ // Numbered title
+ else if (sc.Match("++++++"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER6);
+ sc.Forward();
+ }
+ else if (sc.Match("+++++"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER5);
+ sc.Forward();
+ }
+ else if (sc.Match("++++"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER4);
+ sc.Forward();
+ }
+ else if (sc.Match("+++"))
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER3);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER3, 3, '+', sc);
+ else if (sc.Match("++")) {
+ sc.SetState(SCE_TXT2TAGS_HEADER2);
+ sc.Forward();
+ }
+ //SetStateAndZoom(SCE_TXT2TAGS_HEADER2, 2, '+', sc);
+ else if (sc.Match("+")) {
+ // Catch the special case of an unordered list
+ if (sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(1))) {
+ // if (IsNewline(sc.ch)) {
+ //precharCount = 0;
+ // sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ //sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ // }
+ // else {
+ // precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+ sc.Forward(2);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ // sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ // }
+ }
+ else
+ {
+ sc.SetState(SCE_TXT2TAGS_HEADER1);
+ sc.Forward();
+ }
+ }
+
+
+ // Codeblock
+ else if (sc.Match("```")) {
+ if (!HasPrevLineContent(sc))
+ // if (!FollowToLineEnd(sc))
+ sc.SetState(SCE_TXT2TAGS_CODEBK);
+ else
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+
+ // Preproc
+ else if (sc.Match("%!preproc")) {
+ sc.SetState(SCE_TXT2TAGS_PREPROC);
+ }
+ // Postproc
+ else if (sc.Match("%!postproc")) {
+ sc.SetState(SCE_TXT2TAGS_POSTPROC);
+ }
+ // Option
+ else if (sc.Match("%!")) {
+ sc.SetState(SCE_TXT2TAGS_OPTION);
+ }
+
+ // Comment
+ else if (sc.ch == '%') {
+ sc.SetState(SCE_TXT2TAGS_COMMENT);
+ }
+ // list
+ else if (sc.ch == '-') {
+ precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ }
+ // def list
+ else if (sc.ch == ':') {
+ precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+ sc.Forward(1);
+ sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ }
+ else if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ else {
+ precharCount = 0;
+ sc.SetState(SCE_TXT2TAGS_PRECHAR);
+ }
+ }
+
+ // The header lasts until the newline
+ else if (sc.state == SCE_TXT2TAGS_HEADER1 || sc.state == SCE_TXT2TAGS_HEADER2 ||
+ sc.state == SCE_TXT2TAGS_HEADER3 || sc.state == SCE_TXT2TAGS_HEADER4 ||
+ sc.state == SCE_TXT2TAGS_HEADER5 || sc.state == SCE_TXT2TAGS_HEADER6) {
+ if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ }
+
+ // New state only within the initial whitespace
+ if (sc.state == SCE_TXT2TAGS_PRECHAR) {
+ // Blockquote
+ if (sc.Match("\"\"\"") && precharCount < 5){
+
+ sc.SetState(SCE_TXT2TAGS_BLOCKQUOTE);
+ sc.Forward(1);
+ }
+ /*
+ // Begin of code block
+ else if (!HasPrevLineContent(sc) && (sc.chPrev == '\t' || precharCount >= 4))
+ sc.SetState(SCE_TXT2TAGS_CODEBK);
+ */
+ // HRule - Total of 20 or more hyphens, asterisks, or underscores
+ // on a line by themselves
+ else if ((sc.ch == '-' ) && IsValidHrule(endPos, sc))
+ ;
+ // Unordered list
+ else if ((sc.ch == '-') && IsASpaceOrTab(sc.chNext)) {
+ sc.SetState(SCE_TXT2TAGS_ULIST_ITEM);
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ // Ordered list
+ else if (IsADigit(sc.ch)) {
+ int digitCount = 0;
+ while (IsADigit(sc.GetRelative(++digitCount)))
+ ;
+ if (sc.GetRelative(digitCount) == '.' &&
+ IsASpaceOrTab(sc.GetRelative(digitCount + 1))) {
+ sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+ sc.Forward(digitCount + 1);
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Alternate Ordered list
+ else if (sc.ch == '+' && sc.chNext == ' ' && IsASpaceOrTab(sc.GetRelative(2))) {
+ // sc.SetState(SCE_TXT2TAGS_OLIST_ITEM);
+ // sc.Forward(2);
+ // sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ else if (sc.ch != ' ' || precharCount > 2)
+ sc.SetState(SCE_TXT2TAGS_DEFAULT);
+ else
+ ++precharCount;
+ }
+
+ // New state anywhere in doc
+ if (sc.state == SCE_TXT2TAGS_DEFAULT) {
+ // if (sc.atLineStart && sc.ch == '#') {
+ // sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ // freezeCursor = true;
+ // }
+ // Links and Images
+ if (sc.Match("![") || sc.ch == '[') {
+ int i = 0, j = 0, k = 0;
+ int len = endPos - sc.currentPos;
+ while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+ ;
+ if (sc.GetRelative(i) == ']') {
+ j = i;
+ if (sc.GetRelative(++i) == '(') {
+ while (i < len && (sc.GetRelative(++i) != '(' || sc.GetRelative(i - 1) == '\\'))
+ ;
+ if (sc.GetRelative(i) == '(')
+ k = i;
+ }
+
+ else if (sc.GetRelative(i) == '[' || sc.GetRelative(++i) == '[') {
+ while (i < len && (sc.GetRelative(++i) != ']' || sc.GetRelative(i - 1) == '\\'))
+ ;
+ if (sc.GetRelative(i) == ']')
+ k = i;
+ }
+ }
+ // At least a link text
+ if (j) {
+ sc.SetState(SCE_TXT2TAGS_LINK);
+ sc.Forward(j);
+ // Also has a URL or reference portion
+ if (k)
+ sc.Forward(k - j);
+ sc.ForwardSetState(SCE_TXT2TAGS_DEFAULT);
+ }
+ }
+ // Code - also a special case for alternate inside spacing
+ if (sc.Match("``") && sc.GetRelative(3) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_CODE2);
+ sc.Forward();
+ }
+ else if (sc.ch == '|' && sc.GetRelative(3) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_CODE);
+ }
+ // Strong
+ else if (sc.Match("**") && sc.GetRelative(2) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_STRONG1);
+ sc.Forward();
+ }
+ // Emphasis
+ else if (sc.Match("//") && sc.GetRelative(2) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_EM1);
+ sc.Forward();
+ }
+ else if (sc.Match("__") && sc.GetRelative(2) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_EM2);
+ sc.Forward();
+ }
+ // Strikeout
+ else if (sc.Match("--") && sc.GetRelative(2) != ' ') {
+ sc.SetState(SCE_TXT2TAGS_STRIKEOUT);
+ sc.Forward();
+ }
+
+ // Beginning of line
+ else if (IsNewline(sc.ch))
+ sc.SetState(SCE_TXT2TAGS_LINE_BEGIN);
+ }
+ // Advance if not holding back the cursor for this iteration.
+ if (!freezeCursor)
+ sc.Forward();
+ freezeCursor = false;
+ }
+ sc.Complete();
+}
+
+LexerModule lmTxt2tags(SCLEX_TXT2TAGS, ColorizeTxt2tagsDoc, "txt2tags");
+
+
diff --git a/plugins/scintilla/scintilla/LexVB.cxx b/plugins/scintilla/scintilla/LexVB.cxx
index c57a9ac..54050c7 100644
--- a/plugins/scintilla/scintilla/LexVB.cxx
+++ b/plugins/scintilla/scintilla/LexVB.cxx
@@ -7,18 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
diff --git a/plugins/scintilla/scintilla/LexVHDL.cxx b/plugins/scintilla/scintilla/LexVHDL.cxx
index c082cdb..58bcd1a 100644
--- a/plugins/scintilla/scintilla/LexVHDL.cxx
+++ b/plugins/scintilla/scintilla/LexVHDL.cxx
@@ -1,9 +1,9 @@
// Scintilla source code edit control
/** @file LexVHDL.cxx
** Lexer for VHDL
- ** Written by Phil Reid,
+ ** Written by Phil Reid,
** Based on:
- ** - The Verilog Lexer by Avi Yegudin
+ ** - The Verilog Lexer by Avi Yegudin
** - The Fortran Lexer by Chuan-jian Shen
** - The C++ lexer by Neil Hodgson
**/
@@ -15,15 +15,18 @@
#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -101,7 +104,7 @@ static void ColouriseVHDLDoc(
}
sc.SetState(SCE_VHDL_DEFAULT);
}
- } else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_V_COMMENTLINEBANG) {
+ } else if (sc.state == SCE_VHDL_COMMENT || sc.state == SCE_VHDL_COMMENTLINEBANG) {
if (sc.atLineEnd) {
sc.SetState(SCE_VHDL_DEFAULT);
}
@@ -113,7 +116,7 @@ static void ColouriseVHDLDoc(
} else if (sc.ch == '\"') {
sc.ForwardSetState(SCE_VHDL_DEFAULT);
} else if (sc.atLineEnd) {
- sc.ChangeState(SCE_V_STRINGEOL);
+ sc.ChangeState(SCE_VHDL_STRINGEOL);
sc.ForwardSetState(SCE_VHDL_DEFAULT);
}
}
@@ -126,7 +129,7 @@ static void ColouriseVHDLDoc(
sc.SetState(SCE_VHDL_IDENTIFIER);
} else if (sc.Match('-', '-')) {
sc.SetState(SCE_VHDL_COMMENT);
- sc.Forward();
+ sc.Forward();
} else if (sc.Match('-', '-')) {
if (sc.Match("--!")) // Nice to have a different comment style
sc.SetState(SCE_VHDL_COMMENTLINEBANG);
@@ -161,7 +164,7 @@ static bool IsCommentLine(int line, Accessor &styler) {
static void FoldNoBoxVHDLDoc(
unsigned int startPos,
int length,
- int initStyle,
+ int,
Accessor &styler)
{
// Decided it would be smarter to have the lexer have all keywords included. Therefore I
@@ -249,7 +252,6 @@ static void FoldNoBoxVHDLDoc(
char chPrev = '\0';
char chNextNonBlank;
int styleNext = styler.StyleAt(startPos);
- int style = initStyle;
//Platform::DebugPrintf("Line[%04d] Prev[%20s] ************************* Level[%x]\n", lineCurrent+1, prevWord, levelCurrent);
/***************************************/
@@ -265,16 +267,16 @@ static void FoldNoBoxVHDLDoc(
j ++ ;
chNextNonBlank = styler.SafeGetCharAt(j);
}
- style = styleNext;
+ int style = styleNext;
styleNext = styler.StyleAt(i + 1);
bool atEOL = (ch == '\r' && chNext != '\n') || (ch == '\n');
- if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
+ if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
{
if(!IsCommentLine(lineCurrent-1, styler) && IsCommentLine(lineCurrent+1, styler))
{
levelNext++;
- }
+ }
else if(IsCommentLine(lineCurrent-1, styler) && !IsCommentLine(lineCurrent+1, styler))
{
levelNext--;
@@ -380,7 +382,7 @@ static void FoldNoBoxVHDLDoc(
((strcmp(s, "begin") == 0) && (strcmp(prevWord, "function") == 0)) ||
((strcmp(s, "begin") == 0) && (strcmp(prevWord, "procedure") == 0)))
{
- levelMinCurrentBegin = levelNext - 1;
+ levelMinCurrentBegin = levelNext - 1;
}
//Platform::DebugPrintf("Line[%04d] Prev[%20s] Cur[%20s] Level[%x]\n", lineCurrent+1, prevWord, s, levelCurrent);
strcpy(prevWord, s);
@@ -444,34 +446,34 @@ LexerModule lmVHDL(SCLEX_VHDL, ColouriseVHDLDoc, "vhdl", FoldVHDLDoc, VHDLWordLi
// Keyword:
-// access after alias all architecture array assert attribute begin block body buffer bus case component
-// configuration constant disconnect downto else elsif end entity exit file for function generate generic
-// group guarded if impure in inertial inout is label library linkage literal loop map new next null of
-// on open others out package port postponed procedure process pure range record register reject report
-// return select severity shared signal subtype then to transport type unaffected units until use variable
+// access after alias all architecture array assert attribute begin block body buffer bus case component
+// configuration constant disconnect downto else elsif end entity exit file for function generate generic
+// group guarded if impure in inertial inout is label library linkage literal loop map new next null of
+// on open others out package port postponed procedure process pure range record register reject report
+// return select severity shared signal subtype then to transport type unaffected units until use variable
// wait when while with
//
// Operators:
// abs and mod nand nor not or rem rol ror sla sll sra srl xnor xor
//
// Attributes:
-// left right low high ascending image value pos val succ pred leftof rightof base range reverse_range
-// length delayed stable quiet transaction event active last_event last_active last_value driving
+// left right low high ascending image value pos val succ pred leftof rightof base range reverse_range
+// length delayed stable quiet transaction event active last_event last_active last_value driving
// driving_value simple_name path_name instance_name
//
// Std Functions:
-// now readline read writeline write endfile resolved to_bit to_bitvector to_stdulogic to_stdlogicvector
-// to_stdulogicvector to_x01 to_x01z to_UX01 rising_edge falling_edge is_x shift_left shift_right rotate_left
+// now readline read writeline write endfile resolved to_bit to_bitvector to_stdulogic to_stdlogicvector
+// to_stdulogicvector to_x01 to_x01z to_UX01 rising_edge falling_edge is_x shift_left shift_right rotate_left
// rotate_right resize to_integer to_unsigned to_signed std_match to_01
//
// Std Packages:
-// std ieee work standard textio std_logic_1164 std_logic_arith std_logic_misc std_logic_signed
-// std_logic_textio std_logic_unsigned numeric_bit numeric_std math_complex math_real vital_primitives
+// std ieee work standard textio std_logic_1164 std_logic_arith std_logic_misc std_logic_signed
+// std_logic_textio std_logic_unsigned numeric_bit numeric_std math_complex math_real vital_primitives
// vital_timing
//
// Std Types:
-// boolean bit character severity_level integer real time delay_length natural positive string bit_vector
-// file_open_kind file_open_status line text side width std_ulogic std_ulogic_vector std_logic
+// boolean bit character severity_level integer real time delay_length natural positive string bit_vector
+// file_open_kind file_open_status line text side width std_ulogic std_ulogic_vector std_logic
// std_logic_vector X01 X01Z UX01 UX01Z unsigned signed
//
diff --git a/plugins/scintilla/scintilla/LexVerilog.cxx b/plugins/scintilla/scintilla/LexVerilog.cxx
index 3fd0fc3..8de04ff 100644
--- a/plugins/scintilla/scintilla/LexVerilog.cxx
+++ b/plugins/scintilla/scintilla/LexVerilog.cxx
@@ -8,18 +8,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -150,6 +153,22 @@ static bool IsStreamCommentStyle(int style) {
return style == SCE_V_COMMENT;
}
+static bool IsCommentLine(int line, Accessor &styler) {
+ int pos = styler.LineStart(line);
+ int eolPos = styler.LineStart(line + 1) - 1;
+ for (int i = pos; i < eolPos; i++) {
+ char ch = styler[i];
+ char chNext = styler.SafeGetCharAt(i + 1);
+ int style = styler.StyleAt(i);
+ if (ch == '/' && chNext == '/' &&
+ (style == SCE_V_COMMENTLINE || style == SCE_V_COMMENTLINEBANG)) {
+ return true;
+ } else if (!IsASpaceOrTab(ch)) {
+ return false;
+ }
+ }
+ return false;
+}
// Store both the current line's fold level and the next lines in the
// level store to make it easy to pick up with each increment
// and to make it possible to fiddle the current level for "} else {".
@@ -195,6 +214,15 @@ static void FoldNoBoxVerilogDoc(unsigned int startPos, int length, int initStyle
levelNext--;
}
}
+ if (foldComment && atEOL && IsCommentLine(lineCurrent, styler))
+ {
+ if (!IsCommentLine(lineCurrent - 1, styler)
+ && IsCommentLine(lineCurrent + 1, styler))
+ levelNext++;
+ else if (IsCommentLine(lineCurrent - 1, styler)
+ && !IsCommentLine(lineCurrent+1, styler))
+ levelNext--;
+ }
if (foldComment && (style == SCE_V_COMMENTLINE)) {
if ((ch == '/') && (chNext == '/')) {
char chNext2 = styler.SafeGetCharAt(i + 2);
diff --git a/plugins/scintilla/scintilla/LexYAML.cxx b/plugins/scintilla/scintilla/LexYAML.cxx
index 99f34da..727e8af 100644
--- a/plugins/scintilla/scintilla/LexYAML.cxx
+++ b/plugins/scintilla/scintilla/LexYAML.cxx
@@ -7,18 +7,21 @@
#include <stdlib.h>
#include <string.h>
-#include <ctype.h>
#include <stdio.h>
#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
-#include "Platform.h"
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
-#include "PropSet.h"
+#include "WordList.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
-#include "KeyWords.h"
-#include "Scintilla.h"
-#include "SciLexer.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -270,7 +273,7 @@ static void FoldYAMLDoc(unsigned int startPos, int length, int /*initStyle - unu
}
const int levelAfterComments = indentNext & SC_FOLDLEVELNUMBERMASK;
- const int levelBeforeComments = Platform::Maximum(indentCurrentLevel,levelAfterComments);
+ const int levelBeforeComments = Maximum(indentCurrentLevel,levelAfterComments);
// Now set all the indent levels on the lines we skipped
// Do this from end to start. Once we encounter one line
diff --git a/plugins/scintilla/scintilla/LexerBase.cxx b/plugins/scintilla/scintilla/LexerBase.cxx
new file mode 100644
index 0000000..ea5734d
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerBase.cxx
@@ -0,0 +1,92 @@
+// Scintilla source code edit control
+/** @file LexerSimple.cxx
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerBase::LexerBase() {
+ for (int wl = 0; wl < numWordLists; wl++)
+ keyWordLists[wl] = new WordList;
+ keyWordLists[numWordLists] = 0;
+}
+
+LexerBase::~LexerBase() {
+ for (int wl = 0; wl < numWordLists; wl++) {
+ delete keyWordLists[wl];
+ keyWordLists[wl] = 0;
+ }
+ keyWordLists[numWordLists] = 0;
+}
+
+void SCI_METHOD LexerBase::Release() {
+ delete this;
+}
+
+int SCI_METHOD LexerBase::Version() const {
+ return lvOriginal;
+}
+
+const char * SCI_METHOD LexerBase::PropertyNames() {
+ return "";
+}
+
+int SCI_METHOD LexerBase::PropertyType(const char *) {
+ return SC_TYPE_BOOLEAN;
+}
+
+const char * SCI_METHOD LexerBase::DescribeProperty(const char *) {
+ return "";
+}
+
+int SCI_METHOD LexerBase::PropertySet(const char *key, const char *val) {
+ const char *valOld = props.Get(key);
+ if (strcmp(val, valOld) != 0) {
+ props.Set(key, val);
+ return 0;
+ } else {
+ return -1;
+ }
+}
+
+const char * SCI_METHOD LexerBase::DescribeWordListSets() {
+ return "";
+}
+
+int SCI_METHOD LexerBase::WordListSet(int n, const char *wl) {
+ if (n < numWordLists) {
+ WordList wlNew;
+ wlNew.Set(wl);
+ if (*keyWordLists[n] != wlNew) {
+ keyWordLists[n]->Set(wl);
+ return 0;
+ }
+ }
+ return -1;
+}
+
+void * SCI_METHOD LexerBase::PrivateCall(int, void *) {
+ return 0;
+}
diff --git a/plugins/scintilla/scintilla/LexerBase.h b/plugins/scintilla/scintilla/LexerBase.h
new file mode 100644
index 0000000..2998d24
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerBase.h
@@ -0,0 +1,41 @@
+// Scintilla source code edit control
+/** @file LexerBase.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERBASE_H
+#define LEXERBASE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerBase : public ILexer {
+protected:
+ PropSetSimple props;
+ enum {numWordLists=KEYWORDSET_MAX+1};
+ WordList *keyWordLists[numWordLists+1];
+public:
+ LexerBase();
+ virtual ~LexerBase();
+ void SCI_METHOD Release();
+ int SCI_METHOD Version() const;
+ const char * SCI_METHOD PropertyNames();
+ int SCI_METHOD PropertyType(const char *name);
+ const char * SCI_METHOD DescribeProperty(const char *name);
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ const char * SCI_METHOD DescribeWordListSets();
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ void * SCI_METHOD PrivateCall(int operation, void *pointer);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LexerModule.cxx b/plugins/scintilla/scintilla/LexerModule.cxx
new file mode 100644
index 0000000..defc863
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerModule.cxx
@@ -0,0 +1,121 @@
+// Scintilla source code edit control
+/** @file LexerModule.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <string>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerModule::LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_,
+ LexerFunction fnFolder_,
+ const char *const wordListDescriptions_[],
+ int styleBits_) :
+ language(language_),
+ fnLexer(fnLexer_),
+ fnFolder(fnFolder_),
+ fnFactory(0),
+ wordListDescriptions(wordListDescriptions_),
+ styleBits(styleBits_),
+ languageName(languageName_) {
+}
+
+LexerModule::LexerModule(int language_,
+ LexerFactoryFunction fnFactory_,
+ const char *languageName_,
+ const char * const wordListDescriptions_[],
+ int styleBits_) :
+ language(language_),
+ fnLexer(0),
+ fnFolder(0),
+ fnFactory(fnFactory_),
+ wordListDescriptions(wordListDescriptions_),
+ styleBits(styleBits_),
+ languageName(languageName_) {
+}
+
+int LexerModule::GetNumWordLists() const {
+ if (wordListDescriptions == NULL) {
+ return -1;
+ } else {
+ int numWordLists = 0;
+
+ while (wordListDescriptions[numWordLists]) {
+ ++numWordLists;
+ }
+
+ return numWordLists;
+ }
+}
+
+const char *LexerModule::GetWordListDescription(int index) const {
+ static const char *emptyStr = "";
+
+ assert(index < GetNumWordLists());
+ if (index >= GetNumWordLists()) {
+ return emptyStr;
+ } else {
+ return wordListDescriptions[index];
+ }
+}
+
+int LexerModule::GetStyleBitsNeeded() const {
+ return styleBits;
+}
+
+ILexer *LexerModule::Create() const {
+ if (fnFactory)
+ return fnFactory();
+ else
+ return new LexerSimple(this);
+}
+
+void LexerModule::Lex(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const {
+ if (fnLexer)
+ fnLexer(startPos, lengthDoc, initStyle, keywordlists, styler);
+}
+
+void LexerModule::Fold(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const {
+ if (fnFolder) {
+ int lineCurrent = styler.GetLine(startPos);
+ // Move back one line in case deletion wrecked current line fold state
+ if (lineCurrent > 0) {
+ lineCurrent--;
+ int newStartPos = styler.LineStart(lineCurrent);
+ lengthDoc += startPos - newStartPos;
+ startPos = newStartPos;
+ initStyle = 0;
+ if (startPos > 0) {
+ initStyle = styler.StyleAt(startPos - 1);
+ }
+ }
+ fnFolder(startPos, lengthDoc, initStyle, keywordlists, styler);
+ }
+}
diff --git a/plugins/scintilla/scintilla/LexerModule.h b/plugins/scintilla/scintilla/LexerModule.h
new file mode 100644
index 0000000..e502541
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerModule.h
@@ -0,0 +1,82 @@
+// Scintilla source code edit control
+/** @file LexerModule.h
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERMODULE_H
+#define LEXERMODULE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class Accessor;
+class WordList;
+
+typedef void (*LexerFunction)(unsigned int startPos, int lengthDoc, int initStyle,
+ WordList *keywordlists[], Accessor &styler);
+typedef ILexer *(*LexerFactoryFunction)();
+
+/**
+ * A LexerModule is responsible for lexing and folding a particular language.
+ * The class maintains a list of LexerModules which can be searched to find a
+ * module appropriate to a particular language.
+ */
+class LexerModule {
+protected:
+ int language;
+ LexerFunction fnLexer;
+ LexerFunction fnFolder;
+ LexerFactoryFunction fnFactory;
+ const char * const * wordListDescriptions;
+ int styleBits;
+
+public:
+ const char *languageName;
+ LexerModule(int language_,
+ LexerFunction fnLexer_,
+ const char *languageName_=0,
+ LexerFunction fnFolder_=0,
+ const char * const wordListDescriptions_[] = NULL,
+ int styleBits_=5);
+ LexerModule(int language_,
+ LexerFactoryFunction fnFactory_,
+ const char *languageName_,
+ const char * const wordListDescriptions_[] = NULL,
+ int styleBits_=8);
+ virtual ~LexerModule() {
+ }
+ int GetLanguage() const { return language; }
+
+ // -1 is returned if no WordList information is available
+ int GetNumWordLists() const;
+ const char *GetWordListDescription(int index) const;
+
+ int GetStyleBitsNeeded() const;
+
+ ILexer *Create() const;
+
+ virtual void Lex(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const;
+ virtual void Fold(unsigned int startPos, int length, int initStyle,
+ WordList *keywordlists[], Accessor &styler) const;
+
+ friend class Catalogue;
+};
+
+inline int Maximum(int a, int b) {
+ return (a > b) ? a : b;
+}
+
+// Shut up annoying Visual C++ warnings:
+#ifdef _MSC_VER
+#pragma warning(disable: 4244 4309 4514 4710)
+#endif
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LexerNoExceptions.cxx b/plugins/scintilla/scintilla/LexerNoExceptions.cxx
new file mode 100644
index 0000000..9ebae2a
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerNoExceptions.cxx
@@ -0,0 +1,68 @@
+// Scintilla source code edit control
+/** @file LexerNoExceptions.cxx
+ ** A simple lexer with no state which does not throw exceptions so can be used in an external lexer.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerNoExceptions.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+int SCI_METHOD LexerNoExceptions::PropertySet(const char *key, const char *val) {
+ try {
+ return LexerBase::PropertySet(key, val);
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ }
+ return -1;
+}
+
+int SCI_METHOD LexerNoExceptions::WordListSet(int n, const char *wl) {
+ try {
+ return LexerBase::WordListSet(n, wl);
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ }
+ return -1;
+}
+
+void SCI_METHOD LexerNoExceptions::Lex(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ try {
+ Accessor astyler(pAccess, &props);
+ Lexer(startPos, length, initStyle, pAccess, astyler);
+ astyler.Flush();
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ pAccess->SetErrorStatus(SC_STATUS_FAILURE);
+ }
+}
+void SCI_METHOD LexerNoExceptions::Fold(unsigned int startPos, int length, int initStyle, IDocument *pAccess) {
+ try {
+ Accessor astyler(pAccess, &props);
+ Folder(startPos, length, initStyle, pAccess, astyler);
+ astyler.Flush();
+ } catch (...) {
+ // Should not throw into caller as may be compiled with different compiler or options
+ pAccess->SetErrorStatus(SC_STATUS_FAILURE);
+ }
+}
diff --git a/plugins/scintilla/scintilla/LexerNoExceptions.h b/plugins/scintilla/scintilla/LexerNoExceptions.h
new file mode 100644
index 0000000..caac61a
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerNoExceptions.h
@@ -0,0 +1,32 @@
+// Scintilla source code edit control
+/** @file LexerNoExceptions.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LexerNoExceptions_H
+#define LexerNoExceptions_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerNoExceptions : public LexerBase {
+public:
+ // TODO Also need to prevent exceptions in constructor and destructor
+ int SCI_METHOD PropertySet(const char *key, const char *val);
+ int SCI_METHOD WordListSet(int n, const char *wl);
+ void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *);
+
+ virtual void Lexer(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
+ virtual void Folder(unsigned int startPos, int length, int initStyle, IDocument *pAccess, Accessor &styler) = 0;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LexerSimple.cxx b/plugins/scintilla/scintilla/LexerSimple.cxx
new file mode 100644
index 0000000..4d0e178
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerSimple.cxx
@@ -0,0 +1,57 @@
+// Scintilla source code edit control
+/** @file LexerSimple.cxx
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include <string>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "PropSetSimple.h"
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "LexerModule.h"
+#include "LexerBase.h"
+#include "LexerSimple.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+LexerSimple::LexerSimple(const LexerModule *module_) : module(module_) {
+ for (int wl = 0; wl < module->GetNumWordLists(); wl++) {
+ if (!wordLists.empty())
+ wordLists += "\n";
+ wordLists += module->GetWordListDescription(wl);
+ }
+}
+
+const char * SCI_METHOD LexerSimple::DescribeWordListSets() {
+ return wordLists.c_str();
+}
+
+void SCI_METHOD LexerSimple::Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
+ Accessor astyler(pAccess, &props);
+ module->Lex(startPos, lengthDoc, initStyle, keyWordLists, astyler);
+ astyler.Flush();
+}
+
+void SCI_METHOD LexerSimple::Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) {
+ if (props.GetInt("fold")) {
+ Accessor astyler(pAccess, &props);
+ module->Fold(startPos, lengthDoc, initStyle, keyWordLists, astyler);
+ astyler.Flush();
+ }
+}
diff --git a/plugins/scintilla/scintilla/LexerSimple.h b/plugins/scintilla/scintilla/LexerSimple.h
new file mode 100644
index 0000000..8963193
--- /dev/null
+++ b/plugins/scintilla/scintilla/LexerSimple.h
@@ -0,0 +1,30 @@
+// Scintilla source code edit control
+/** @file LexerSimple.h
+ ** A simple lexer with no state.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef LEXERSIMPLE_H
+#define LEXERSIMPLE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+// A simple lexer with no state
+class LexerSimple : public LexerBase {
+ const LexerModule *module;
+ std::string wordLists;
+public:
+ LexerSimple(const LexerModule *module_);
+ const char * SCI_METHOD DescribeWordListSets();
+ void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+ void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess);
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/LineMarker.cxx b/plugins/scintilla/scintilla/LineMarker.cxx
index 0bfd479..73410e2 100644
--- a/plugins/scintilla/scintilla/LineMarker.cxx
+++ b/plugins/scintilla/scintilla/LineMarker.cxx
@@ -2,7 +2,7 @@
/** @file LineMarker.cxx
** Defines the look of a line marker in the margin .
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#include <string.h>
@@ -20,6 +20,7 @@ using namespace Scintilla;
void LineMarker::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(fore, want);
pal.WantFind(back, want);
+ pal.WantFind(backSelected, want);
if (pxpm) {
pxpm->RefreshColourPalette(pal, want);
}
@@ -31,7 +32,7 @@ void LineMarker::SetXPM(const char *textForm) {
markType = SC_MARK_PIXMAP;
}
-void LineMarker::SetXPM(const char * const *linesForm) {
+void LineMarker::SetXPM(const char *const *linesForm) {
delete pxpm;
pxpm = new XPM(linesForm);
markType = SC_MARK_PIXMAP;
@@ -67,7 +68,32 @@ static void DrawMinus(Surface *surface, int centreX, int centreY, int armSize, C
surface->FillRectangle(rcH, fore);
}
-void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter) {
+void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharacter, typeOfFold tFold) {
+ ColourPair head = back;
+ ColourPair body = back;
+ ColourPair tail = back;
+
+ switch (tFold) {
+ case LineMarker::head :
+ head = backSelected;
+ tail = backSelected;
+ if (markType == SC_MARK_VLINE)
+ body = backSelected;
+ break;
+ case LineMarker::body :
+ head = backSelected;
+ body = backSelected;
+ break;
+ case LineMarker::tail :
+ body = backSelected;
+ tail = backSelected;
+ break;
+ default :
+ // LineMarker::undefined
+ break;
+ }
+
+
if ((markType == SC_MARK_PIXMAP) && (pxpm)) {
pxpm->Draw(surface, rcWhole);
return;
@@ -154,111 +180,143 @@ void LineMarker::Draw(Surface *surface, PRectangle &rcWhole, Font &fontForCharac
rcSmall.bottom = rc.bottom - 2;
surface->RectangleDraw(rcSmall, fore.allocated, back.allocated);
- } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND ||
+ } else if (markType == SC_MARK_EMPTY || markType == SC_MARK_BACKGROUND ||
markType == SC_MARK_UNDERLINE || markType == SC_MARK_AVAILABLE) {
// An invisible marker so don't draw anything
} else if (markType == SC_MARK_VLINE) {
- surface->PenColour(back.allocated);
- surface->MoveTo(centreX, rcWhole.top);
+ surface->PenColour(body.allocated);
+ surface->MoveTo(centreX, rcWhole.top + blobSize - (rcWhole.bottom - rcWhole.top)/2);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_LCORNER) {
- surface->PenColour(back.allocated);
+ surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNER) {
- surface->PenColour(back.allocated);
- surface->MoveTo(centreX, rcWhole.top);
- surface->LineTo(centreX, rcWhole.bottom);
+ surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rc.top + dimOn2);
surface->LineTo(rc.right - 2, rc.top + dimOn2);
+ surface->PenColour(body.allocated);
+ surface->MoveTo(centreX, rcWhole.top);
+ surface->LineTo(centreX, rc.top + dimOn2 + 1);
+
+ surface->PenColour(head.allocated);
+ surface->LineTo(centreX, rcWhole.bottom);
+
} else if (markType == SC_MARK_LCORNERCURVE) {
- surface->PenColour(back.allocated);
+ surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2);
} else if (markType == SC_MARK_TCORNERCURVE) {
- surface->PenColour(back.allocated);
- surface->MoveTo(centreX, rcWhole.top);
- surface->LineTo(centreX, rcWhole.bottom);
-
+ surface->PenColour(tail.allocated);
surface->MoveTo(centreX, rc.top + dimOn2-3);
surface->LineTo(centreX+3, rc.top + dimOn2);
surface->LineTo(rc.right - 1, rc.top + dimOn2);
+ surface->PenColour(body.allocated);
+ surface->MoveTo(centreX, rcWhole.top);
+ surface->LineTo(centreX, rc.top + dimOn2-2);
+
+ surface->PenColour(head.allocated);
+ surface->LineTo(centreX, rcWhole.bottom);
+
} else if (markType == SC_MARK_BOXPLUS) {
- surface->PenColour(back.allocated);
- DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+ DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_BOXPLUSCONNECTED) {
- surface->PenColour(back.allocated);
- DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-
+ surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
+ surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
+ DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+ DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
+
+ if (tFold == LineMarker::body) {
+ surface->PenColour(tail.allocated);
+ surface->MoveTo(centreX + 1, centreY + blobSize);
+ surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
+
+ surface->MoveTo(centreX + blobSize, centreY + blobSize);
+ surface->LineTo(centreX + blobSize, centreY - blobSize);
+
+ surface->MoveTo(centreX + 1, centreY - blobSize);
+ surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
+ }
} else if (markType == SC_MARK_BOXMINUS) {
- surface->PenColour(back.allocated);
- DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+ DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
+ surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_BOXMINUSCONNECTED) {
- surface->PenColour(back.allocated);
- DrawBox(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawBox(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+ DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
+ surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
+ surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
+ if (tFold == LineMarker::body) {
+ surface->PenColour(tail.allocated);
+ surface->MoveTo(centreX + 1, centreY + blobSize);
+ surface->LineTo(centreX + blobSize + 1, centreY + blobSize);
+
+ surface->MoveTo(centreX + blobSize, centreY + blobSize);
+ surface->LineTo(centreX + blobSize, centreY - blobSize);
+
+ surface->MoveTo(centreX + 1, centreY - blobSize);
+ surface->LineTo(centreX + blobSize + 1, centreY - blobSize);
+ }
} else if (markType == SC_MARK_CIRCLEPLUS) {
- DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- surface->PenColour(back.allocated);
- DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+ DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
} else if (markType == SC_MARK_CIRCLEPLUSCONNECTED) {
- DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- surface->PenColour(back.allocated);
- DrawPlus(surface, centreX, centreY, blobSize, back.allocated);
-
+ surface->PenColour(body.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
+ DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+ DrawPlus(surface, centreX, centreY, blobSize, tail.allocated);
+
} else if (markType == SC_MARK_CIRCLEMINUS) {
- DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- surface->PenColour(back.allocated);
- DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+ DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
+ surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
} else if (markType == SC_MARK_CIRCLEMINUSCONNECTED) {
- DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, back.allocated);
- surface->PenColour(back.allocated);
- DrawMinus(surface, centreX, centreY, blobSize, back.allocated);
+ DrawCircle(surface, centreX, centreY, blobSize, fore.allocated, head.allocated);
+ DrawMinus(surface, centreX, centreY, blobSize, tail.allocated);
+ surface->PenColour(head.allocated);
surface->MoveTo(centreX, centreY + blobSize);
surface->LineTo(centreX, rcWhole.bottom);
+ surface->PenColour(body.allocated);
surface->MoveTo(centreX, rcWhole.top);
surface->LineTo(centreX, centreY - blobSize);
diff --git a/plugins/scintilla/scintilla/LineMarker.h b/plugins/scintilla/scintilla/LineMarker.h
index 3cb4139..39c38fa 100644
--- a/plugins/scintilla/scintilla/LineMarker.h
+++ b/plugins/scintilla/scintilla/LineMarker.h
@@ -2,7 +2,7 @@
/** @file LineMarker.h
** Defines the look of a line marker in the margin .
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2011 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
#ifndef LINEMARKER_H
@@ -12,19 +12,24 @@
namespace Scintilla {
#endif
+
/**
*/
class LineMarker {
public:
+ enum typeOfFold { undefined, head, body, tail };
+
int markType;
ColourPair fore;
ColourPair back;
+ ColourPair backSelected;
int alpha;
XPM *pxpm;
LineMarker() {
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
+ backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
}
@@ -33,6 +38,7 @@ public:
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
+ backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
pxpm = NULL;
}
@@ -44,6 +50,7 @@ public:
markType = SC_MARK_CIRCLE;
fore = ColourDesired(0,0,0);
back = ColourDesired(0xff,0xff,0xff);
+ backSelected = ColourDesired(0xff,0x00,0x00);
alpha = SC_ALPHA_NOALPHA;
delete pxpm;
pxpm = NULL;
@@ -51,8 +58,8 @@ public:
}
void RefreshColourPalette(Palette &pal, bool want);
void SetXPM(const char *textForm);
- void SetXPM(const char * const *linesForm);
- void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter);
+ void SetXPM(const char *const *linesForm);
+ void Draw(Surface *surface, PRectangle &rc, Font &fontForCharacter, typeOfFold tFold);
};
#ifdef SCI_NAMESPACE
diff --git a/plugins/scintilla/scintilla/Makefile.am b/plugins/scintilla/scintilla/Makefile.am
index 42c4eee..dec5b51 100644
--- a/plugins/scintilla/scintilla/Makefile.am
+++ b/plugins/scintilla/scintilla/Makefile.am
@@ -15,24 +15,25 @@ AM_CXXFLAGS = -DGTK -DSCI_LEXER -DUSE_XIM
include $(srcdir)/lexers.make
libanjuta_scintilla_la_SOURCES =\
+ Accessor.cxx \
AutoComplete.cxx \
CallTip.cxx \
+ Catalogue.cxx \
CellBuffer.cxx \
CharClassify.cxx \
+ CharacterSet.cxx \
ContractionState.cxx \
Decoration.cxx \
- DocumentAccessor.cxx \
Document.cxx \
Editor.cxx \
ExternalLexer.cxx \
Indicator.cxx \
KeyMap.cxx \
- KeyWords.cxx \
LineMarker.cxx \
PerLine.cxx \
PlatGTK.cxx \
PositionCache.cxx \
- PropSet.cxx \
+ PropSetSimple.cxx \
RESearch.cxx \
RunStyles.cxx \
ScintillaBase.cxx \
@@ -42,23 +43,26 @@ libanjuta_scintilla_la_SOURCES =\
Style.cxx \
UniConversion.cxx \
ViewStyle.cxx \
- WindowAccessor.cxx \
+ WordList.cxx \
XPM.cxx\
+ Accessor.h \
AutoComplete.h \
CallTip.h \
+ Catalogue.h \
CellBuffer.h \
CharacterSet.h \
CharClassify.h \
ContractionState.h \
Converter.h \
Decoration.h \
- DocumentAccessor.h \
Document.h \
Editor.h \
ExternalLexer.h \
Indicator.h \
KeyMap.h \
+ LexAccessor.h \
LineMarker.h \
+ OptionSet.h \
Partitioning.h \
PerLine.h \
PositionCache.h \
@@ -67,12 +71,14 @@ libanjuta_scintilla_la_SOURCES =\
RunStyles.h \
ScintillaBase.h \
Selection.h \
+ SparseState.h \
SplitVector.h \
StyleContext.h\
Style.h \
SVector.h \
UniConversion.h \
ViewStyle.h\
+ WordList.h \
XPM.h\
scintilla-marshal.h\
scintilla-marshal.c\
@@ -88,6 +94,25 @@ test_scintilla_CXXFLAGS = -DGTK
test_scintilla_SOURCES = test-scintilla.cxx
test_scintilla_LDADD = libanjuta-scintilla.la
+$(srcdir)/lexers.make:
+ cd $(srcdir); \
+ echo "## Lexers make file" > $(notdir $@); \
+ echo 'LEXER_OBJS = \' >> $(notdir $@); \
+ echo -n ' StyleContext.o' >> $(notdir $@); \
+ for lex in Lex*.cxx; do \
+ lex=`echo $$lex | sed -e "s,.*/,," -e "s/cxx$$/o/"`; \
+ echo '\' >> $(notdir $@); \
+ echo -n " $$lex" >> $(notdir $@); \
+ done; \
+ echo "" >> $(notdir $@); \
+ echo "" >> $(notdir $@); \
+ echo -n 'LEXER_SRCS = ' >> $(notdir $@); \
+ for lex in Lex*.cxx; do \
+ echo '\' >> $(notdir $@); \
+ echo -n " $$lex" >> $(notdir $@); \
+ done; \
+ echo "" >> $(notdir $@)
+
update-scintilla:
cd $(srcdir); \
cp scintilla/gtk/*.cxx .; \
@@ -97,22 +122,6 @@ update-scintilla:
cp scintilla/include/*.h include; \
cp scintilla/include/*.py include; \
cp scintilla/include/*.iface include; \
- echo "## Lexers make file" > lexers.make; \
- echo 'LEXER_OBJS = \' >> lexers.make; \
- echo -n ' StyleContext.o' >> lexers.make; \
- for lex in Lex*.cxx; do \
- lex=`echo $$lex | sed -e "s,.*/,," -e "s/cxx$$/o/"`; \
- echo '\' >> lexers.make; \
- echo -n " $$lex" >> lexers.make; \
- done; \
- echo "" >> lexers.make; \
- echo "" >> lexers.make; \
- echo -n 'LEXER_SRCS = ' >> lexers.make; \
- for lex in Lex*.cxx; do \
- echo '\' >> lexers.make; \
- echo -n " $$lex" >> lexers.make; \
- done; \
- echo "" >> lexers.make
echo "Patching files ..."
cd $(srcdir); \
for patchfile in patches/*.diff; do \
diff --git a/plugins/scintilla/scintilla/OptionSet.h b/plugins/scintilla/scintilla/OptionSet.h
new file mode 100644
index 0000000..873ac8b
--- /dev/null
+++ b/plugins/scintilla/scintilla/OptionSet.h
@@ -0,0 +1,142 @@
+// Scintilla source code edit control
+/** @file OptionSet.h
+ ** Manage descriptive information about an options struct for a lexer.
+ ** Hold the names, positions, and descriptions of boolean, integer and string options and
+ ** allow setting options and retrieving metadata about the options.
+ **/
+// Copyright 2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef OPTIONSET_H
+#define OPTIONSET_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+template <typename T>
+class OptionSet {
+ typedef T Target;
+ typedef bool T::*plcob;
+ typedef int T::*plcoi;
+ typedef std::string T::*plcos;
+ struct Option {
+ int opType;
+ union {
+ plcob pb;
+ plcoi pi;
+ plcos ps;
+ };
+ std::string description;
+ Option() :
+ opType(SC_TYPE_BOOLEAN), pb(0), description("") {
+ }
+ Option(plcob pb_, std::string description_="") :
+ opType(SC_TYPE_BOOLEAN), pb(pb_), description(description_) {
+ }
+ Option(plcoi pi_, std::string description_) :
+ opType(SC_TYPE_INTEGER), pi(pi_), description(description_) {
+ }
+ Option(plcos ps_, std::string description_) :
+ opType(SC_TYPE_STRING), ps(ps_), description(description_) {
+ }
+ bool Set(T *base, const char *val) {
+ switch (opType) {
+ case SC_TYPE_BOOLEAN: {
+ bool option = atoi(val) != 0;
+ if ((*base).*pb != option) {
+ (*base).*pb = option;
+ return true;
+ }
+ break;
+ }
+ case SC_TYPE_INTEGER: {
+ int option = atoi(val);
+ if ((*base).*pi != option) {
+ (*base).*pi = option;
+ return true;
+ }
+ break;
+ }
+ case SC_TYPE_STRING: {
+ if ((*base).*ps != val) {
+ (*base).*ps = val;
+ return true;
+ }
+ break;
+ }
+ }
+ return false;
+ }
+ };
+ typedef std::map<std::string, Option> OptionMap;
+ OptionMap nameToDef;
+ std::string names;
+ std::string wordLists;
+
+ void AppendName(const char *name) {
+ if (!names.empty())
+ names += "\n";
+ names += name;
+ }
+public:
+ virtual ~OptionSet() {
+ }
+ void DefineProperty(const char *name, plcob pb, std::string description="") {
+ nameToDef[name] = Option(pb, description);
+ AppendName(name);
+ }
+ void DefineProperty(const char *name, plcoi pi, std::string description="") {
+ nameToDef[name] = Option(pi, description);
+ AppendName(name);
+ }
+ void DefineProperty(const char *name, plcos ps, std::string description="") {
+ nameToDef[name] = Option(ps, description);
+ AppendName(name);
+ }
+ const char *PropertyNames() {
+ return names.c_str();
+ }
+ int PropertyType(const char *name) {
+ typename OptionMap::iterator it = nameToDef.find(name);
+ if (it != nameToDef.end()) {
+ return it->second.opType;
+ }
+ return SC_TYPE_BOOLEAN;
+ }
+ const char *DescribeProperty(const char *name) {
+ typename OptionMap::iterator it = nameToDef.find(name);
+ if (it != nameToDef.end()) {
+ return it->second.description.c_str();
+ }
+ return "";
+ }
+
+ bool PropertySet(T *base, const char *name, const char *val) {
+ typename OptionMap::iterator it = nameToDef.find(name);
+ if (it != nameToDef.end()) {
+ return it->second.Set(base, val);
+ }
+ return false;
+ }
+
+ void DefineWordListSets(const char * const wordListDescriptions[]) {
+ if (wordListDescriptions) {
+ for (size_t wl = 0; wordListDescriptions[wl]; wl++) {
+ if (!wordLists.empty())
+ wordLists += "\n";
+ wordLists += wordListDescriptions[wl];
+ }
+ }
+ }
+
+ const char *DescribeWordListSets() {
+ return wordLists.c_str();
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/Partitioning.h b/plugins/scintilla/scintilla/Partitioning.h
index 225e350..07f3c5d 100644
--- a/plugins/scintilla/scintilla/Partitioning.h
+++ b/plugins/scintilla/scintilla/Partitioning.h
@@ -8,7 +8,7 @@
#ifndef PARTITIONING_H
#define PARTITIONING_H
-/// A split vector of integers with a method for adding a value to all elements
+/// A split vector of integers with a method for adding a value to all elements
/// in a range.
/// Used by the Partitioning class.
@@ -42,6 +42,10 @@ public:
/// Divide an interval into multiple partitions.
/// Useful for breaking a document down into sections such as lines.
+/// A 0 length interval has a single 0 length partition, numbered 0
+/// If interval not 0 length then each partition non-zero length
+/// When needed, positions after the interval are considered part of the last partition
+/// but the end of the last partition can be found with PositionFromPartition(last+1).
class Partitioning {
private:
@@ -153,6 +157,7 @@ public:
return pos;
}
+ /// Return value in range [0 .. Partitions() - 1] even for arguments outside interval
int PartitionFromPosition(int pos) const {
if (body->Length() <= 1)
return 0;
diff --git a/plugins/scintilla/scintilla/PerLine.cxx b/plugins/scintilla/scintilla/PerLine.cxx
index 3e02d65..8fc6e25 100644
--- a/plugins/scintilla/scintilla/PerLine.cxx
+++ b/plugins/scintilla/scintilla/PerLine.cxx
@@ -202,15 +202,19 @@ int LineMarkers::AddMark(int line, int markerNum, int lines) {
return handleCurrent;
}
-void LineMarkers::DeleteMark(int line, int markerNum, bool all) {
+bool LineMarkers::DeleteMark(int line, int markerNum, bool all) {
+ bool someChanges = false;
if (markers.Length() && (line >= 0) && (line < markers.Length()) && markers[line]) {
if (markerNum == -1) {
+ someChanges = true;
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;
}
if (markers[line]->Length() == 0) {
delete markers[line];
@@ -218,6 +222,7 @@ void LineMarkers::DeleteMark(int line, int markerNum, bool all) {
}
}
}
+ return someChanges;
}
void LineMarkers::DeleteMarkFromHandle(int markerHandle) {
@@ -240,10 +245,7 @@ void LineLevels::Init() {
void LineLevels::InsertLine(int line) {
if (levels.Length()) {
- int level = SC_FOLDLEVELBASE;
- if ((line > 0) && (line < levels.Length())) {
- level = levels[line-1] & ~SC_FOLDLEVELWHITEFLAG;
- }
+ int level = (line < levels.Length()) ? levels[line] : SC_FOLDLEVELBASE;
levels.InsertValue(line, 1, level);
}
}
@@ -301,7 +303,8 @@ void LineState::Init() {
void LineState::InsertLine(int line) {
if (lineStates.Length()) {
lineStates.EnsureLength(line);
- lineStates.Insert(line, 0);
+ int val = (line < lineStates.Length()) ? lineStates[line] : 0;
+ lineStates.Insert(line, val);
}
}
@@ -319,6 +322,8 @@ int LineState::SetLineState(int line, int state) {
}
int LineState::GetLineState(int line) {
+ if (line < 0)
+ return 0;
lineStates.EnsureLength(line + 1);
return lineStates[line];
}
@@ -421,7 +426,7 @@ void LineAnnotation::SetText(int line, const char *text) {
delete []annotations[line];
}
annotations[line] = AllocateAnnotation(strlen(text), style);
- AnnotationHeader *pah = reinterpret_cast<AnnotationHeader*>(annotations[line]);
+ AnnotationHeader *pah = reinterpret_cast<AnnotationHeader *>(annotations[line]);
pah->style = static_cast<short>(style);
pah->length = strlen(text);
pah->lines = static_cast<short>(NumberLines(text));
diff --git a/plugins/scintilla/scintilla/PerLine.h b/plugins/scintilla/scintilla/PerLine.h
index ab34c46..df47286 100644
--- a/plugins/scintilla/scintilla/PerLine.h
+++ b/plugins/scintilla/scintilla/PerLine.h
@@ -11,7 +11,7 @@
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
-
+
/**
* This holds the marker identifier and the marker type to display.
* MarkerHandleNumbers are members of lists.
@@ -56,7 +56,7 @@ public:
int MarkValue(int line);
int AddMark(int line, int marker, int lines);
void MergeMarkers(int pos);
- void DeleteMark(int line, int markerNum, bool all);
+ bool DeleteMark(int line, int markerNum, bool all);
void DeleteMarkFromHandle(int markerHandle);
int LineFromHandle(int markerHandle);
};
diff --git a/plugins/scintilla/scintilla/PlatGTK.cxx b/plugins/scintilla/scintilla/PlatGTK.cxx
index 35f8d93..ee74c65 100644
--- a/plugins/scintilla/scintilla/PlatGTK.cxx
+++ b/plugins/scintilla/scintilla/PlatGTK.cxx
@@ -7,6 +7,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <stddef.h>
+#include <math.h>
#include <glib.h>
#include <gmodule.h>
@@ -31,9 +32,28 @@
with gdk_string_extents. */
#define FAST_WAY
-#if GTK_MAJOR_VERSION >= 2
-#define USE_PANGO 1
#include "Converter.h"
+
+#if GTK_CHECK_VERSION(2,20,0)
+#define IS_WIDGET_FOCUSSED(w) (gtk_widget_has_focus(GTK_WIDGET(w)))
+#else
+#define IS_WIDGET_FOCUSSED(w) (GTK_WIDGET_HAS_FOCUS(w))
+#endif
+
+#if GTK_CHECK_VERSION(2,22,0)
+#define USE_CAIRO 1
+#endif
+
+static GdkWindow *WindowFromWidget(GtkWidget *w) {
+#if GTK_CHECK_VERSION(3,0,0)
+ return gtk_widget_get_window(w);
+#else
+ return w->window;
+#endif
+}
+
+#ifdef USE_CAIRO
+#define DISABLE_GDK_FONT 1
#endif
#ifdef _MSC_VER
@@ -104,40 +124,44 @@ class FontHandle {
encodingType et;
public:
int ascent;
+#ifndef DISABLE_GDK_FONT
GdkFont *pfont;
-#ifdef USE_PANGO
+#endif
PangoFontDescription *pfd;
int characterSet;
-#endif
- FontHandle(GdkFont *pfont_) {
+#ifdef DISABLE_GDK_FONT
+ FontHandle() : et(singleByte), ascent(0), pfd(0), characterSet(-1) {
+ ResetWidths(et);
+ }
+#else
+ FontHandle(GdkFont *pfont_=0) {
et = singleByte;
ascent = 0;
pfont = pfont_;
-#ifdef USE_PANGO
pfd = 0;
characterSet = -1;
-#endif
ResetWidths(et);
}
-#ifdef USE_PANGO
+#endif
FontHandle(PangoFontDescription *pfd_, int characterSet_) {
et = singleByte;
ascent = 0;
+#ifndef DISABLE_GDK_FONT
pfont = 0;
+#endif
pfd = pfd_;
characterSet = characterSet_;
ResetWidths(et);
}
-#endif
~FontHandle() {
+#ifndef DISABLE_GDK_FONT
if (pfont)
gdk_font_unref(pfont);
pfont = 0;
-#ifdef USE_PANGO
+#endif
if (pfd)
pango_font_description_free(pfd);
pfd = 0;
-#endif
}
void ResetWidths(encodingType et_) {
et = et_;
@@ -177,9 +201,11 @@ static GtkWidget *PWidget(WindowID wid) {
return reinterpret_cast<GtkWidget *>(wid);
}
+#if !GTK_CHECK_VERSION(3,0,0)
static GtkWidget *PWidget(Window &w) {
return PWidget(w.GetID());
}
+#endif
Point Point::FromLong(long lpoint) {
return Point(
@@ -248,6 +274,8 @@ void Palette::WantFind(ColourPair &cp, bool want) {
}
void Palette::Allocate(Window &w) {
+#if !GTK_CHECK_VERSION(3,0,0)
+ // Disable palette on GTK+ 3.
if (allocatedPalette) {
gdk_colormap_free_colors(gtk_widget_get_colormap(PWidget(w)),
reinterpret_cast<GdkColor *>(allocatedPalette),
@@ -276,8 +304,11 @@ void Palette::Allocate(Window &w) {
}
}
delete []successPalette;
+#endif
}
+#ifndef DISABLE_GDK_FONT
+
static const char *CharacterSetName(int characterSet) {
switch (characterSet) {
case SC_CHARSET_ANSI:
@@ -358,7 +389,7 @@ static void GenerateFontSpecStrings(const char *fontName, int characterSet,
d2 = strchr(d1 + 1, '-');
if (d2)
d3 = strchr(d2 + 1, '-');
- if (d3) {
+ if (d3 && d2) {
// foundary-fontface-isoxxx-x
*d2 = '\0';
foundary[0] = '-';
@@ -385,6 +416,8 @@ static void GenerateFontSpecStrings(const char *fontName, int characterSet,
}
}
+#endif
+
static void SetLogFont(LOGFONT &lf, const char *faceName, int characterSet, int size, bool bold, bool italic) {
memset(&lf, 0, sizeof(lf));
lf.size = size;
@@ -492,6 +525,7 @@ void FontCached::ReleaseId(FontID fid_) {
FontMutexUnlock();
}
+#ifndef DISABLE_GDK_FONT
static GdkFont *LoadFontOrSet(const char *fontspec, int characterSet) {
if (IsDBCSCharacterSet(characterSet)) {
return gdk_fontset_load(fontspec);
@@ -499,9 +533,22 @@ static GdkFont *LoadFontOrSet(const char *fontspec, int characterSet) {
return gdk_font_load(fontspec);
}
}
+#endif
FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
int size, bool bold, bool italic) {
+ if (fontName[0] == '!') {
+ PangoFontDescription *pfd = pango_font_description_new();
+ if (pfd) {
+ pango_font_description_set_family(pfd, fontName+1);
+ pango_font_description_set_size(pfd, size * PANGO_SCALE);
+ pango_font_description_set_weight(pfd, bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
+ pango_font_description_set_style(pfd, italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
+ return new FontHandle(pfd, characterSet);
+ }
+ }
+
+#ifndef DISABLE_GDK_FONT
char fontset[1024];
char fontspec[300];
char foundary[50];
@@ -513,19 +560,6 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
faceName[0] = '\0';
charset[0] = '\0';
-#ifdef USE_PANGO
- //if (fontName[0] == '!') {
- PangoFontDescription *pfd = pango_font_description_new();
- if (pfd) {
- pango_font_description_set_family(pfd, fontName);
- pango_font_description_set_size(pfd, size * PANGO_SCALE);
- pango_font_description_set_weight(pfd, bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
- pango_font_description_set_style(pfd, italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
- return new FontHandle(pfd, characterSet);
- }
- //}
-#endif
-
GdkFont *newid = 0;
// If name of the font begins with a '-', assume, that it is
// a full fontspec.
@@ -611,7 +645,6 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
newid = gdk_fontset_load(fontset);
if (newid)
return new FontHandle(newid);
-
// if fontset load failed, fall through, we'll use
// the last font entry and continue to try and
// get something that matches
@@ -660,6 +693,18 @@ FontID FontCached::CreateNewFont(const char *fontName, int characterSet,
characterSet);
}
return new FontHandle(newid);
+#else
+ PangoFontDescription *pfd = pango_font_description_new();
+ if (pfd) {
+ pango_font_description_set_family(pfd, fontName+1);
+ pango_font_description_set_size(pfd, size * PANGO_SCALE);
+ pango_font_description_set_weight(pfd, bold ? PANGO_WEIGHT_BOLD : PANGO_WEIGHT_NORMAL);
+ pango_font_description_set_style(pfd, italic ? PANGO_STYLE_ITALIC : PANGO_STYLE_NORMAL);
+ return new FontHandle(pfd, characterSet);
+ }
+
+ return new FontHandle();
+#endif
}
Font::Font() : fid(0) {}
@@ -680,26 +725,29 @@ void Font::Release() {
// Required on OS X
#ifdef SCI_NAMESPACE
-class Scintilla::SurfaceImpl : public Surface
-#else
-class SurfaceImpl : public Surface
+namespace Scintilla {
#endif
-{
+
+// On GTK+ 2.x, SurfaceID is a GdkDrawable* and on GTK+ 3.x, it is a cairo_t*
+class SurfaceImpl : public Surface {
encodingType et;
+#ifdef USE_CAIRO
+ cairo_t *context;
+ cairo_surface_t *psurf;
+#else
GdkDrawable *drawable;
GdkGC *gc;
GdkPixmap *ppixmap;
+#endif
int x;
int y;
bool inited;
bool createdGC;
-#ifdef USE_PANGO
PangoContext *pcontext;
PangoLayout *layout;
Converter conv;
int characterSet;
void SetConverter(int characterSet_);
-#endif
public:
SurfaceImpl();
virtual ~SurfaceImpl();
@@ -746,6 +794,9 @@ public:
void SetUnicodeMode(bool unicodeMode_);
void SetDBCSMode(int codePage);
};
+#ifdef SCI_NAMESPACE
+}
+#endif
const char *CharacterSetID(int characterSet) {
switch (characterSet) {
@@ -760,11 +811,11 @@ const char *CharacterSetID(int characterSet) {
case SC_CHARSET_EASTEUROPE:
return "ISO-8859-2";
case SC_CHARSET_GB2312:
- return "GB2312";
+ return "CP936";
case SC_CHARSET_GREEK:
return "ISO-8859-7";
case SC_CHARSET_HANGUL:
- return "";
+ return "CP949";
case SC_CHARSET_MAC:
return "MACINTOSH";
case SC_CHARSET_OEM:
@@ -780,7 +831,7 @@ const char *CharacterSetID(int characterSet) {
case SC_CHARSET_TURKISH:
return "ISO-8859-9";
case SC_CHARSET_JOHAB:
- return "JOHAB";
+ return "CP1361";
case SC_CHARSET_HEBREW:
return "ISO-8859-8";
case SC_CHARSET_ARABIC:
@@ -796,22 +847,24 @@ const char *CharacterSetID(int characterSet) {
}
}
-#ifdef USE_PANGO
-
void SurfaceImpl::SetConverter(int characterSet_) {
if (characterSet != characterSet_) {
characterSet = characterSet_;
conv.Open("UTF-8", CharacterSetID(characterSet), false);
}
}
-#endif
-SurfaceImpl::SurfaceImpl() : et(singleByte), drawable(0), gc(0), ppixmap(0),
-x(0), y(0), inited(false), createdGC(false)
-#ifdef USE_PANGO
-, pcontext(0), layout(0), characterSet(-1)
+SurfaceImpl::SurfaceImpl() : et(singleByte),
+#ifdef USE_CAIRO
+context(0),
+psurf(0),
+#else
+drawable(0),
+gc(0),
+ppixmap(0),
#endif
-{
+x(0), y(0), inited(false), createdGC(false)
+, pcontext(0), layout(0), characterSet(-1) {
}
SurfaceImpl::~SurfaceImpl() {
@@ -820,16 +873,28 @@ SurfaceImpl::~SurfaceImpl() {
void SurfaceImpl::Release() {
et = singleByte;
+#ifndef USE_CAIRO
drawable = 0;
+#endif
if (createdGC) {
createdGC = false;
- gdk_gc_unref(gc);
+#ifdef USE_CAIRO
+ cairo_destroy(context);
+#else
+ g_object_unref(gc);
+#endif
}
+#ifdef USE_CAIRO
+ context = 0;
+ if (psurf)
+ cairo_surface_destroy(psurf);
+ psurf = 0;
+#else
gc = 0;
if (ppixmap)
- gdk_pixmap_unref(ppixmap);
+ g_object_unref(ppixmap);
ppixmap = 0;
-#ifdef USE_PANGO
+#endif
if (layout)
g_object_unref(layout);
layout = 0;
@@ -838,7 +903,6 @@ void SurfaceImpl::Release() {
pcontext = 0;
conv.Close();
characterSet = -1;
-#endif
x = 0;
y = 0;
inited = false;
@@ -849,70 +913,127 @@ bool SurfaceImpl::Initialised() {
return inited;
}
-// The WindowID argument is only used for Pango builds
-#ifdef USE_PANGO
-#define WID_NAME wid
-#else
-#define WID_NAME
-#endif
-
-void SurfaceImpl::Init(WindowID WID_NAME) {
+void SurfaceImpl::Init(WindowID wid) {
Release();
-#ifdef USE_PANGO
PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+#if GTK_CHECK_VERSION(3,0,0)
+ GdkWindow *drawable_ = gtk_widget_get_window(PWidget(wid));
+#else
+ GdkDrawable *drawable_ = GDK_DRAWABLE(PWidget(wid)->window);
+#endif
+ if (drawable_) {
+ context = gdk_cairo_create(drawable_);
+ PLATFORM_ASSERT(context);
+ } else {
+ // Shouldn't happen with valid window but may when calls made before
+ // window completely allocated and mapped.
+ psurf = cairo_image_surface_create(CAIRO_FORMAT_RGB24, 1, 1);
+ context = cairo_create(psurf);
+ }
+ createdGC = true;
+#endif
pcontext = gtk_widget_create_pango_context(PWidget(wid));
PLATFORM_ASSERT(pcontext);
layout = pango_layout_new(pcontext);
PLATFORM_ASSERT(layout);
-#endif
inited = true;
}
-void SurfaceImpl::Init(SurfaceID sid, WindowID WID_NAME) {
+void SurfaceImpl::Init(SurfaceID sid, WindowID wid) {
PLATFORM_ASSERT(sid);
- GdkDrawable *drawable_ = reinterpret_cast<GdkDrawable *>(sid);
Release();
-#ifdef USE_PANGO
PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+#if GTK_CHECK_VERSION(3,0,0)
+ context = cairo_reference(reinterpret_cast<cairo_t *>(sid));
+#else
+ context = gdk_cairo_create(reinterpret_cast<GdkDrawable *>(sid));
+#endif
+#else
+ drawable = reinterpret_cast<GdkDrawable *>(sid);
+ gc = gdk_gc_new(drawable);
+#endif
pcontext = gtk_widget_create_pango_context(PWidget(wid));
layout = pango_layout_new(pcontext);
-#endif
- drawable = drawable_;
- gc = gdk_gc_new(drawable_);
+#ifdef USE_CAIRO
+ cairo_set_line_width(context, 1);
+#else
// Ask for lines that do not paint the last pixel so is like Win32
gdk_gc_set_line_attributes(gc, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+#endif
createdGC = true;
inited = true;
}
-void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID WID_NAME) {
+void SurfaceImpl::InitPixMap(int width, int height, Surface *surface_, WindowID wid) {
PLATFORM_ASSERT(surface_);
Release();
SurfaceImpl *surfImpl = static_cast<SurfaceImpl *>(surface_);
- PLATFORM_ASSERT(surfImpl->drawable);
-#ifdef USE_PANGO
PLATFORM_ASSERT(wid);
+#ifdef USE_CAIRO
+ context = cairo_reference(surfImpl->context);
+#else
+ PLATFORM_ASSERT(surfImpl->drawable);
+ gc = gdk_gc_new(surfImpl->drawable);
+#endif
pcontext = gtk_widget_create_pango_context(PWidget(wid));
PLATFORM_ASSERT(pcontext);
layout = pango_layout_new(pcontext);
PLATFORM_ASSERT(layout);
-#endif
+#ifdef USE_CAIRO
+ if (height > 0 && width > 0)
+ psurf = gdk_window_create_similar_surface(
+ gtk_widget_get_window(PWidget(wid)),
+ CAIRO_CONTENT_COLOR_ALPHA, width, height);
+#else
if (height > 0 && width > 0)
ppixmap = gdk_pixmap_new(surfImpl->drawable, width, height, -1);
drawable = ppixmap;
- gc = gdk_gc_new(surfImpl->drawable);
+#endif
+#ifdef USE_CAIRO
+ cairo_destroy(context);
+ context = cairo_create(psurf);
+ cairo_rectangle(context, 0, 0, width, height);
+ cairo_set_source_rgb(context, 1.0, 0, 0);
+ cairo_fill(context);
+ // This produces sharp drawing more similar to GDK:
+ //cairo_set_antialias(context, CAIRO_ANTIALIAS_NONE);
+#endif
+#ifdef USE_CAIRO
+ cairo_set_line_width(context, 1);
+#else
// Ask for lines that do not paint the last pixel so is like Win32
gdk_gc_set_line_attributes(gc, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_MITER);
+#endif
createdGC = true;
inited = true;
}
void SurfaceImpl::PenColour(ColourAllocated fore) {
+#ifdef USE_CAIRO
+ if (context) {
+ ColourDesired cdFore(fore.AsLong());
+#if GTK_CHECK_VERSION(3,0,0)
+ // Colours appear inverted - possibly because palette no longer used
+ cairo_set_source_rgb(context,
+ cdFore.GetRed() / 255.0,
+ cdFore.GetGreen() / 255.0,
+ cdFore.GetBlue() / 255.0);
+#else
+ cairo_set_source_rgb(context,
+ cdFore.GetBlue() / 255.0,
+ cdFore.GetGreen() / 255.0,
+ cdFore.GetRed() / 255.0);
+#endif
+ }
+#else
if (gc) {
GdkColor co;
co.pixel = fore.AsLong();
gdk_gc_set_foreground(gc, &co);
}
+#endif
}
int SurfaceImpl::LogPixelsY() {
@@ -929,18 +1050,71 @@ void SurfaceImpl::MoveTo(int x_, int y_) {
y = y_;
}
+#ifdef USE_CAIRO
+static int Delta(int difference) {
+ if (difference < 0)
+ return -1;
+ else if (difference > 0)
+ return 1;
+ else
+ return 0;
+}
+#endif
+
void SurfaceImpl::LineTo(int x_, int y_) {
+#ifdef USE_CAIRO
+ // cairo_line_to draws the end position, unlike Win32 or GDK with GDK_CAP_NOT_LAST.
+ // For simple cases, move back one pixel from end.
+ if (context) {
+ int xDiff = x_ - x;
+ int xDelta = Delta(xDiff);
+ int yDiff = y_ - y;
+ int yDelta = Delta(yDiff);
+ if ((xDiff == 0) || (yDiff == 0)) {
+ // Horizontal or vertical lines can be more precisely drawn as a filled rectangle
+ int xEnd = x_ - xDelta;
+ int left = Platform::Minimum(x, xEnd);
+ int width = abs(x - xEnd) + 1;
+ int yEnd = y_ - yDelta;
+ int top = Platform::Minimum(y, yEnd);
+ int height = abs(y - yEnd) + 1;
+ cairo_rectangle(context, left, top, width, height);
+ cairo_fill(context);
+ } else if ((abs(xDiff) == abs(yDiff))) {
+ // 45 degree slope
+ cairo_move_to(context, x + 0.5, y + 0.5);
+ cairo_line_to(context, x_ + 0.5 - xDelta, y_ + 0.5 - yDelta);
+ } else {
+ // Line has a different slope so difficult to avoid last pixel
+ cairo_move_to(context, x + 0.5, y + 0.5);
+ cairo_line_to(context, x_ + 0.5, y_ + 0.5);
+ }
+ cairo_stroke(context);
+ }
+#else
if (drawable && gc) {
gdk_draw_line(drawable, gc,
x, y,
x_, y_);
}
+#endif
x = x_;
y = y_;
}
void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore,
ColourAllocated back) {
+#ifdef USE_CAIRO
+ PenColour(back);
+ cairo_move_to(context, pts[0].x + 0.5, pts[0].y + 0.5);
+ for (int i = 1;i < npts;i++) {
+ cairo_line_to(context, pts[i].x + 0.5, pts[i].y + 0.5);
+ }
+ cairo_close_path(context);
+ cairo_fill_preserve(context);
+ PenColour(fore);
+ cairo_stroke(context);
+#else
GdkPoint gpts[20];
if (npts < static_cast<int>((sizeof(gpts) / sizeof(gpts[0])))) {
for (int i = 0;i < npts;i++) {
@@ -952,35 +1126,62 @@ void SurfaceImpl::Polygon(Point *pts, int npts, ColourAllocated fore,
PenColour(fore);
gdk_draw_polygon(drawable, gc, 0, gpts, npts);
}
+#endif
}
void SurfaceImpl::RectangleDraw(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
+#ifdef USE_CAIRO
+ if (context) {
+#else
if (gc && drawable) {
+#endif
+#ifdef USE_CAIRO
+ cairo_rectangle(context, rc.left + 0.5, rc.top + 0.5,
+ rc.right - rc.left - 1, rc.bottom - rc.top - 1);
+ PenColour(back);
+ cairo_fill_preserve(context);
+ PenColour(fore);
+ cairo_stroke(context);
+#else
PenColour(back);
gdk_draw_rectangle(drawable, gc, 1,
rc.left + 1, rc.top + 1,
rc.right - rc.left - 2, rc.bottom - rc.top - 2);
-
PenColour(fore);
// The subtraction of 1 off the width and height here shouldn't be needed but
// otherwise a different rectangle is drawn than would be done if the fill parameter == 1
gdk_draw_rectangle(drawable, gc, 0,
rc.left, rc.top,
rc.right - rc.left - 1, rc.bottom - rc.top - 1);
+#endif
}
}
void SurfaceImpl::FillRectangle(PRectangle rc, ColourAllocated back) {
PenColour(back);
+#ifdef USE_CAIRO
+ if (context && (rc.left < maxCoordinate)) { // Protect against out of range
+ cairo_rectangle(context, rc.left, rc.top,
+ rc.right - rc.left, rc.bottom - rc.top);
+ cairo_fill(context);
+ }
+#else
if (drawable && (rc.left < maxCoordinate)) { // Protect against out of range
gdk_draw_rectangle(drawable, gc, 1,
rc.left, rc.top,
rc.right - rc.left, rc.bottom - rc.top);
}
+#endif
}
void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
- if (static_cast<SurfaceImpl &>(surfacePattern).drawable) {
+ SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfacePattern);
+#ifdef USE_CAIRO
+ bool canDraw = surfi.psurf;
+#else
+ bool canDraw = surfi.drawable;
+#endif
+ if (canDraw) {
// Tile pattern over rectangle
// Currently assumes 8x8 pattern
int widthPat = 8;
@@ -989,12 +1190,18 @@ void SurfaceImpl::FillRectangle(PRectangle rc, Surface &surfacePattern) {
int widthx = (xTile + widthPat > rc.right) ? rc.right - xTile : widthPat;
for (int yTile = rc.top; yTile < rc.bottom; yTile += heightPat) {
int heighty = (yTile + heightPat > rc.bottom) ? rc.bottom - yTile : heightPat;
- gdk_draw_pixmap(drawable,
+#ifdef USE_CAIRO
+ cairo_set_source_surface(context, surfi.psurf, xTile, yTile);
+ cairo_rectangle(context, xTile, yTile, widthx, heighty);
+ cairo_fill(context);
+#else
+ gdk_draw_drawable(drawable,
gc,
static_cast<SurfaceImpl &>(surfacePattern).drawable,
0, 0,
xTile, yTile,
widthx, heighty);
+#endif
}
}
} else {
@@ -1023,7 +1230,20 @@ void SurfaceImpl::RoundedRectangle(PRectangle rc, ColourAllocated fore, ColourAl
}
}
-#if GTK_MAJOR_VERSION >= 2
+#ifdef USE_CAIRO
+
+static void PathRoundRectangle(cairo_t *context, double left, double top, double width, double height, int radius) {
+ double degrees = M_PI / 180.0;
+
+ cairo_new_sub_path(context);
+ cairo_arc(context, left + width - radius, top + radius, radius, -90 * degrees, 0 * degrees);
+ cairo_arc(context, left + width - radius, top + height - radius, radius, 0 * degrees, 90 * degrees);
+ cairo_arc(context, left + radius, top + height - radius, radius, 90 * degrees, 180 * degrees);
+ cairo_arc(context, left + radius, top + radius, radius, 180 * degrees, 270 * degrees);
+ cairo_close_path(context);
+}
+
+#else
// Plot a point into a guint32 buffer symetrically to all 4 qudrants
static void AllFour(guint32 *pixels, int stride, int width, int height, int x, int y, guint32 val) {
@@ -1033,32 +1253,6 @@ static void AllFour(guint32 *pixels, int stride, int width, int height, int x, i
pixels[(height-1-y)*stride+width-1-x] = val;
}
-static unsigned int GetRValue(unsigned int co) {
- return (co >> 16) & 0xff;
-}
-
-static unsigned int GetGValue(unsigned int co) {
- return (co >> 8) & 0xff;
-}
-
-static unsigned int GetBValue(unsigned int co) {
- return co & 0xff;
-}
-
-#endif
-
-#if GTK_MAJOR_VERSION < 2
-void SurfaceImpl::AlphaRectangle(PRectangle rc, int , ColourAllocated , int , ColourAllocated outline, int , int ) {
- if (gc && drawable) {
- // Can't use GdkPixbuf on GTK+ 1.x, so draw an outline rather than use alpha.
- PenColour(outline);
- gdk_draw_rectangle(drawable, gc, 0,
- rc.left, rc.top,
- rc.right - rc.left - 1, rc.bottom - rc.top - 1);
- }
-}
-#else
-
static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
union {
guint8 pixVal[4];
@@ -1071,8 +1265,41 @@ static guint32 u32FromRGBA(guint8 r, guint8 g, guint8 b, guint8 a) {
return converter.val;
}
+#endif
+
+static unsigned int GetRValue(unsigned int co) {
+ return (co >> 16) & 0xff;
+}
+
+static unsigned int GetGValue(unsigned int co) {
+ return (co >> 8) & 0xff;
+}
+
+static unsigned int GetBValue(unsigned int co) {
+ return co & 0xff;
+}
+
void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated fill, int alphaFill,
ColourAllocated outline, int alphaOutline, int flags) {
+#ifdef USE_CAIRO
+ if (context && rc.Width() > 0) {
+ cairo_set_source_rgba(context,
+ GetRValue(fill.AsLong()) / 255.0,
+ GetGValue(fill.AsLong()) / 255.0,
+ GetBValue(fill.AsLong()) / 255.0,
+ alphaFill / 255.0);
+ PathRoundRectangle(context, rc.left + 1.0, rc.top+1.0, rc.right - rc.left - 2.0, rc.bottom - rc.top - 2.0, cornerSize);
+ cairo_fill(context);
+
+ cairo_set_source_rgba(context,
+ GetRValue(outline.AsLong()) / 255.0,
+ GetGValue(outline.AsLong()) / 255.0,
+ GetBValue(outline.AsLong()) / 255.0,
+ alphaOutline / 255.0);
+ PathRoundRectangle(context, rc.left +0.5, rc.top+0.5, rc.right - rc.left - 1, rc.bottom - rc.top - 1, cornerSize);
+ cairo_stroke(context);
+ }
+#else
if (gc && drawable && rc.Width() > 0) {
int width = rc.Width();
int height = rc.Height();
@@ -1082,9 +1309,9 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
GdkPixbuf *pixalpha = gdk_pixbuf_new(GDK_COLORSPACE_RGB, TRUE, 8, width, height);
guint32 valEmpty = u32FromRGBA(0,0,0,0);
- guint32 valFill = u32FromRGBA(GetRValue(fill.AsLong()),
+ guint32 valFill = u32FromRGBA(GetRValue(fill.AsLong()),
GetGValue(fill.AsLong()), GetBValue(fill.AsLong()), alphaFill);
- guint32 valOutline = u32FromRGBA(GetRValue(outline.AsLong()),
+ guint32 valOutline = u32FromRGBA(GetRValue(outline.AsLong()),
GetGValue(outline.AsLong()), GetBValue(outline.AsLong()), alphaOutline);
guint32 *pixels = reinterpret_cast<guint32 *>(gdk_pixbuf_get_pixels(pixalpha));
int stride = gdk_pixbuf_get_rowstride(pixalpha) / 4;
@@ -1112,12 +1339,18 @@ void SurfaceImpl::AlphaRectangle(PRectangle rc, int cornerSize, ColourAllocated
g_object_unref(pixalpha);
}
-}
-
#endif
+}
void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated back) {
PenColour(back);
+#ifdef USE_CAIRO
+ cairo_arc(context, (rc.left + rc.right) / 2 + 0.5, (rc.top + rc.bottom) / 2 + 0.5,
+ Platform::Minimum(rc.Width(), rc.Height()) / 2, 0, 2*M_PI);
+ cairo_fill_preserve(context);
+ PenColour(fore);
+ cairo_stroke(context);
+#else
gdk_draw_arc(drawable, gc, 1,
rc.left + 1, rc.top + 1,
rc.right - rc.left - 2, rc.bottom - rc.top - 2,
@@ -1129,19 +1362,34 @@ void SurfaceImpl::Ellipse(PRectangle rc, ColourAllocated fore, ColourAllocated b
rc.left, rc.top,
rc.right - rc.left - 1, rc.bottom - rc.top - 1,
0, 32767);
+#endif
}
void SurfaceImpl::Copy(PRectangle rc, Point from, Surface &surfaceSource) {
- if (static_cast<SurfaceImpl &>(surfaceSource).drawable) {
- gdk_draw_pixmap(drawable,
+ SurfaceImpl &surfi = static_cast<SurfaceImpl &>(surfaceSource);
+#ifdef USE_CAIRO
+ bool canDraw = surfi.psurf;
+#else
+ bool canDraw = surfi.drawable;
+#endif
+ if (canDraw) {
+#ifdef USE_CAIRO
+ cairo_set_source_surface(context, surfi.psurf,
+ rc.left - from.x, rc.top - from.y);
+ cairo_rectangle(context, rc.left, rc.top, rc.right-rc.left, rc.bottom-rc.top);
+ cairo_fill(context);
+#else
+ gdk_draw_drawable(drawable,
gc,
static_cast<SurfaceImpl &>(surfaceSource).drawable,
from.x, from.y,
rc.left, rc.top,
rc.right - rc.left, rc.bottom - rc.top);
+#endif
}
}
+#ifndef DISABLE_GDK_FONT
static size_t UTF8Len(char ch) {
unsigned char uch = static_cast<unsigned char>(ch);
if (uch < 0x80)
@@ -1151,6 +1399,7 @@ static size_t UTF8Len(char ch) {
else
return 3;
}
+#endif
char *UTF8FromLatin1(const char *s, int &len) {
char *utfForm = new char[len*2+1];
@@ -1169,7 +1418,6 @@ char *UTF8FromLatin1(const char *s, int &len) {
return utfForm;
}
-#ifdef USE_PANGO
static char *UTF8FromIconv(const Converter &conv, const char *s, int &len) {
if (conv) {
char *utfForm = new char[len*3+1];
@@ -1205,6 +1453,7 @@ static size_t MultiByteLenFromIconv(const Converter &conv, const char *s, size_t
return 1;
}
+#ifndef DISABLE_GDK_FONT
static char *UTF8FromGdkWChar(GdkWChar *wctext, int wclen) {
char *utfForm = new char[wclen*3+1]; // Maximum of 3 UTF-8 bytes per character
size_t lenU = 0;
@@ -1224,8 +1473,10 @@ static char *UTF8FromGdkWChar(GdkWChar *wctext, int wclen) {
utfForm[lenU] = '\0';
return utfForm;
}
+#endif
static char *UTF8FromDBCS(const char *s, int &len) {
+#ifndef DISABLE_GDK_FONT
GdkWChar *wctext = new GdkWChar[len + 1];
GdkWChar *wcp = wctext;
int wclen = gdk_mbstowcs(wcp, s, len);
@@ -1240,6 +1491,9 @@ static char *UTF8FromDBCS(const char *s, int &len) {
delete []wctext;
len = strlen(utfForm);
return utfForm;
+#else
+ return 0;
+#endif
}
static size_t UTF8CharLength(const char *s) {
@@ -1254,8 +1508,6 @@ static size_t UTF8CharLength(const char *s) {
}
}
-#endif
-
// On GTK+, wchar_t is 4 bytes
const int maxLengthTextRun = 10000;
@@ -1263,9 +1515,12 @@ const int maxLengthTextRun = 10000;
void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char *s, int len,
ColourAllocated fore) {
PenColour(fore);
+#ifdef USE_CAIRO
+ if (context) {
+#else
if (gc && drawable) {
+#endif
int xText = rc.left;
-#ifdef USE_PANGO
if (PFont(font_)->pfd) {
char *utfForm = 0;
bool useGFree = false;
@@ -1288,12 +1543,20 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
pango_layout_set_text(layout, utfForm, len);
}
pango_layout_set_font_description(layout, PFont(font_)->pfd);
+#ifdef USE_CAIRO
+ pango_cairo_update_layout(context, layout);
+#endif
#ifdef PANGO_VERSION
PangoLayoutLine *pll = pango_layout_get_line_readonly(layout,0);
#else
PangoLayoutLine *pll = pango_layout_get_line(layout,0);
#endif
+#ifdef USE_CAIRO
+ cairo_move_to(context, xText, ybase);
+ pango_cairo_show_layout_line(context, pll);
+#else
gdk_draw_layout_line(drawable, gc, xText, ybase, pll);
+#endif
if (useGFree) {
g_free(utfForm);
} else {
@@ -1301,7 +1564,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
}
return;
}
-#endif
+#ifndef DISABLE_GDK_FONT
// Draw text as a series of segments to avoid limitations in X servers
const int segmentLength = 1000;
bool draw8bit = true;
@@ -1349,6 +1612,7 @@ void SurfaceImpl::DrawTextBase(PRectangle rc, Font &font_, int ybase, const char
s += lenDraw;
}
}
+#endif
}
}
@@ -1376,8 +1640,6 @@ void SurfaceImpl::DrawTextTransparent(PRectangle rc, Font &font_, int ybase, con
}
}
-#ifdef USE_PANGO
-
class ClusterIterator {
PangoLayoutIter *iter;
PangoRectangle pos;
@@ -1388,8 +1650,8 @@ public:
int position;
int distance;
int curIndex;
- ClusterIterator(PangoLayout *layout, int len) : lenPositions(len), finished(false),
- positionStart(0), position(0), distance(0) {
+ ClusterIterator(PangoLayout *layout, int len) : lenPositions(len), finished(false),
+ positionStart(0), position(0), distance(0), curIndex(0) {
iter = pango_layout_get_iter(layout);
pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
}
@@ -1397,7 +1659,7 @@ public:
pango_layout_iter_free(iter);
}
- void Next() {
+ void Next() {
positionStart = position;
if (pango_layout_iter_next_cluster(iter)) {
pango_layout_iter_get_cluster_extents(iter, NULL, &pos);
@@ -1412,12 +1674,8 @@ public:
}
};
-#endif
-
void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positions) {
if (font_.GetID()) {
- int totalWidth = 0;
-#ifdef USE_PANGO
const int lenPositions = len;
if (PFont(font_)->pfd) {
if (len == 1) {
@@ -1516,7 +1774,8 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
}
return;
}
-#endif
+#ifndef DISABLE_GDK_FONT
+ int totalWidth = 0;
GdkFont *gf = PFont(font_)->pfont;
bool measure8bit = true;
if (et != singleByte) {
@@ -1567,6 +1826,7 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
positions[i] = totalWidth;
}
}
+#endif
} else {
// No font so return an ascending range of values
for (int i = 0; i < len; i++) {
@@ -1577,7 +1837,6 @@ void SurfaceImpl::MeasureWidths(Font &font_, const char *s, int len, int *positi
int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
if (font_.GetID()) {
-#ifdef USE_PANGO
if (PFont(font_)->pfd) {
char *utfForm = 0;
pango_layout_set_font_description(layout, PFont(font_)->pfd);
@@ -1612,7 +1871,7 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
}
return PANGO_PIXELS(pos.width);
}
-#endif
+#ifndef DISABLE_GDK_FONT
if (et == UTF8) {
GdkWChar wctext[maxLengthTextRun];
size_t wclen = UTF16FromUTF8(s, len, static_cast<wchar_t *>(static_cast<void *>(wctext)),
@@ -1622,6 +1881,9 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
} else {
return gdk_text_width(PFont(font_)->pfont, s, len);
}
+#else
+ return 1;
+#endif
} else {
return 1;
}
@@ -1629,12 +1891,14 @@ int SurfaceImpl::WidthText(Font &font_, const char *s, int len) {
int SurfaceImpl::WidthChar(Font &font_, char ch) {
if (font_.GetID()) {
-#ifdef USE_PANGO
if (PFont(font_)->pfd) {
return WidthText(font_, &ch, 1);
}
-#endif
+#ifndef DISABLE_GDK_FONT
return gdk_char_width(PFont(font_)->pfont, ch);
+#else
+ return 1;
+#endif
} else {
return 1;
}
@@ -1663,7 +1927,6 @@ int SurfaceImpl::Ascent(Font &font_) {
#ifdef FAST_WAY
FontMutexLock();
int ascent = PFont(font_)->ascent;
-#ifdef USE_PANGO
if ((ascent == 0) && (PFont(font_)->pfd)) {
PangoFontMetrics *metrics = pango_context_get_metrics(pcontext,
PFont(font_)->pfd, pango_context_get_language(pcontext));
@@ -1672,10 +1935,11 @@ int SurfaceImpl::Ascent(Font &font_) {
pango_font_metrics_unref(metrics);
ascent = PFont(font_)->ascent;
}
-#endif
+#ifndef DISABLE_GDK_FONT
if ((ascent == 0) && (PFont(font_)->pfont)) {
ascent = PFont(font_)->pfont->ascent;
}
+#endif
if (ascent == 0) {
ascent = 1;
}
@@ -1700,7 +1964,6 @@ int SurfaceImpl::Descent(Font &font_) {
return 1;
#ifdef FAST_WAY
-#ifdef USE_PANGO
if (PFont(font_)->pfd) {
PangoFontMetrics *metrics = pango_context_get_metrics(pcontext,
PFont(font_)->pfd, pango_context_get_language(pcontext));
@@ -1708,9 +1971,12 @@ int SurfaceImpl::Descent(Font &font_) {
pango_font_metrics_unref(metrics);
return descent;
}
-#endif
+#ifndef DISABLE_GDK_FONT
return PFont(font_)->pfont->descent;
#else
+ return 0;
+#endif
+#else
gint lbearing;
gint rbearing;
@@ -1746,9 +2012,14 @@ int SurfaceImpl::SetPalette(Palette *, bool) {
}
void SurfaceImpl::SetClip(PRectangle rc) {
+#ifdef USE_CAIRO
+ cairo_rectangle(context, rc.left, rc.top, rc.right, rc.bottom);
+ cairo_clip(context);
+#else
GdkRectangle area = {rc.left, rc.top,
rc.right - rc.left, rc.bottom - rc.top};
gdk_gc_set_clip_rectangle(gc, &area);
+#endif
}
void SurfaceImpl::FlushCachedState() {}
@@ -1776,42 +2047,42 @@ void Window::Destroy() {
}
bool Window::HasFocus() {
- return GTK_WIDGET_HAS_FOCUS(wid);
+ return IS_WIDGET_FOCUSSED(wid);
}
PRectangle Window::GetPosition() {
// Before any size allocated pretend its 1000 wide so not scrolled
PRectangle rc(0, 0, 1000, 1000);
if (wid) {
- rc.left = PWidget(wid)->allocation.x;
- rc.top = PWidget(wid)->allocation.y;
- if (PWidget(wid)->allocation.width > 20) {
- rc.right = rc.left + PWidget(wid)->allocation.width;
- rc.bottom = rc.top + PWidget(wid)->allocation.height;
+ GtkAllocation allocation;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_get_allocation(PWidget(wid), &allocation);
+#else
+ allocation = PWidget(wid)->allocation;
+#endif
+ rc.left = allocation.x;
+ rc.top = allocation.y;
+ if (allocation.width > 20) {
+ rc.right = rc.left + allocation.width;
+ rc.bottom = rc.top + allocation.height;
}
}
return rc;
}
void Window::SetPosition(PRectangle rc) {
-#if 1
GtkAllocation alloc;
alloc.x = rc.left;
alloc.y = rc.top;
alloc.width = rc.Width();
alloc.height = rc.Height();
gtk_widget_size_allocate(PWidget(wid), &alloc);
-#else
-
- gtk_widget_set_uposition(wid, rc.left, rc.top);
- gtk_widget_set_size_request(wid, rc.right - rc.left, rc.bottom - rc.top);
-#endif
}
void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
int ox = 0;
int oy = 0;
- gdk_window_get_origin(PWidget(relativeTo.wid)->window, &ox, &oy);
+ gdk_window_get_origin(WindowFromWidget(PWidget(relativeTo.wid)), &ox, &oy);
ox += rc.left;
if (ox < 0)
ox = 0;
@@ -1831,21 +2102,8 @@ void Window::SetPositionRelative(PRectangle rc, Window relativeTo) {
if (oy + sizey > screenHeight)
oy = screenHeight - sizey;
-#if GTK_MAJOR_VERSION >= 2
gtk_window_move(GTK_WINDOW(PWidget(wid)), ox, oy);
-#else
- gtk_widget_set_uposition(PWidget(wid), ox, oy);
-#endif
-#if 0
-
- GtkAllocation alloc;
- alloc.x = rc.left + ox;
- alloc.y = rc.top + oy;
- alloc.width = rc.right - rc.left;
- alloc.height = rc.bottom - rc.top;
- gtk_widget_size_allocate(wid, &alloc);
-#endif
gtk_widget_set_size_request(PWidget(wid), sizex, sizey);
}
@@ -1910,9 +2168,9 @@ void Window::SetCursor(Cursor curs) {
break;
}
- if (PWidget(wid)->window)
- gdk_window_set_cursor(PWidget(wid)->window, gdkCurs);
- gdk_cursor_destroy(gdkCurs);
+ if (WindowFromWidget(PWidget(wid)))
+ gdk_window_set_cursor(WindowFromWidget(PWidget(wid)), gdkCurs);
+ gdk_cursor_unref(gdkCurs);
}
void Window::SetTitle(const char *s) {
@@ -1923,12 +2181,11 @@ void Window::SetTitle(const char *s) {
gdk window coordinates */
PRectangle Window::GetMonitorRect(Point pt) {
gint x_offset, y_offset;
- pt = pt;
- gdk_window_get_origin(PWidget(wid)->window, &x_offset, &y_offset);
+ gdk_window_get_origin(WindowFromWidget(PWidget(wid)), &x_offset, &y_offset);
-// gtk 2.2+
-#if GTK_MAJOR_VERSION > 2 || (GTK_MAJOR_VERSION == 2 && GTK_MINOR_VERSION >= 2)
+#if GTK_CHECK_VERSION(2,2,0)
+ // GTK+ 2.2+
{
GdkScreen* screen;
gint monitor_num;
@@ -1942,6 +2199,7 @@ PRectangle Window::GetMonitorRect(Point pt) {
return PRectangle(rect.x, rect.y, rect.x + rect.width, rect.y + rect.height);
}
#else
+ pt = pt;
return PRectangle(-x_offset, -y_offset, (-x_offset) + gdk_screen_width(),
(-y_offset) + gdk_screen_height());
#endif
@@ -1949,25 +2207,13 @@ PRectangle Window::GetMonitorRect(Point pt) {
struct ListImage {
const char *xpm_data;
-#if GTK_MAJOR_VERSION < 2
- GdkPixmap *pixmap;
- GdkBitmap *bitmap;
-#else
GdkPixbuf *pixbuf;
-#endif
};
static void list_image_free(gpointer, gpointer value, gpointer) {
ListImage *list_image = (ListImage *) value;
-#if GTK_MAJOR_VERSION < 2
- if (list_image->pixmap)
- gdk_pixmap_unref(list_image->pixmap);
- if (list_image->bitmap)
- gdk_bitmap_unref(list_image->bitmap);
-#else
if (list_image->pixbuf)
- g_object_unref (list_image->pixbuf);
-#endif
+ g_object_unref(list_image->pixbuf);
g_free(list_image);
}
@@ -1977,24 +2223,17 @@ ListBox::ListBox() {
ListBox::~ListBox() {
}
-#if GTK_MAJOR_VERSION >= 2
enum {
PIXBUF_COLUMN,
TEXT_COLUMN,
N_COLUMNS
};
-#endif
class ListBoxX : public ListBox {
WindowID list;
WindowID scroller;
-#if GTK_MAJOR_VERSION < 2
- int current;
-#endif
void *pixhash;
-#if GTK_MAJOR_VERSION >= 2
- GtkCellRenderer* pixbuf_renderer;
-#endif
+ GtkCellRenderer* pixbuf_renderer;
XPMSet xset;
int desiredVisibleRows;
unsigned int maxItemCharacters;
@@ -2003,15 +2242,9 @@ public:
CallBackAction doubleClickAction;
void *doubleClickActionData;
- ListBoxX() : list(0), pixhash(NULL),
+ ListBoxX() : list(0), scroller(0), pixhash(NULL), pixbuf_renderer(0),
desiredVisibleRows(5), maxItemCharacters(0),
aveCharWidth(1), doubleClickAction(NULL), doubleClickActionData(NULL) {
-#if GTK_MAJOR_VERSION < 2
- current = 0;
-#endif
-#if GTK_MAJOR_VERSION >= 2
- pixbuf_renderer = 0;
-#endif
}
virtual ~ListBoxX() {
if (pixhash) {
@@ -2047,19 +2280,6 @@ ListBox *ListBox::Allocate() {
return lb;
}
-#if GTK_MAJOR_VERSION < 2
-static void UnselectionAC(GtkWidget *, gint, gint,
- GdkEventButton *, gpointer p) {
- int *pi = reinterpret_cast<int *>(p);
- *pi = -1;
-}
-static void SelectionAC(GtkWidget *, gint row, gint,
- GdkEventButton *, gpointer p) {
- int *pi = reinterpret_cast<int *>(p);
- *pi = row;
-}
-#endif
-
static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
try {
ListBoxX* lb = reinterpret_cast<ListBoxX*>(p);
@@ -2074,30 +2294,51 @@ static gboolean ButtonPress(GtkWidget *, GdkEventButton* ev, gpointer p) {
return FALSE;
}
-#if GTK_MAJOR_VERSION >= 2
/* Change the active color to the selected color so the listbox uses the color
scheme that it would use if it had the focus. */
static void StyleSet(GtkWidget *w, GtkStyle*, void*) {
- GtkStyle* style;
g_return_if_fail(w != NULL);
/* Copy the selected color to active. Note that the modify calls will cause
recursive calls to this function after the value is updated and w->style to
be set to a new object */
- style = gtk_widget_get_style(w);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkStyleContext *styleContext = gtk_widget_get_style_context(w);
+ if (styleContext == NULL)
+ return;
+
+ GdkRGBA colourForeSelected;
+ gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourForeSelected);
+ GdkRGBA colourForeActive;
+ gtk_style_context_get_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourForeActive);
+ if (!gdk_rgba_equal(&colourForeSelected, &colourForeActive))
+ gtk_widget_override_color(w, GTK_STATE_FLAG_ACTIVE, &colourForeSelected);
+
+ styleContext = gtk_widget_get_style_context(w);
+ if (styleContext == NULL)
+ return;
+
+ GdkRGBA colourBaseSelected;
+ gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_SELECTED, &colourBaseSelected);
+ GdkRGBA colourBaseActive;
+ gtk_style_context_get_background_color(styleContext, GTK_STATE_FLAG_ACTIVE, &colourBaseActive);
+ if (!gdk_rgba_equal(&colourBaseSelected, &colourBaseActive))
+ gtk_widget_override_background_color(w, GTK_STATE_FLAG_ACTIVE, &colourBaseSelected);
+#else
+ GtkStyle *style = gtk_widget_get_style(w);
if (style == NULL)
return;
if (!gdk_color_equal(&style->base[GTK_STATE_SELECTED], &style->base[GTK_STATE_ACTIVE]))
gtk_widget_modify_base(w, GTK_STATE_ACTIVE, &style->base[GTK_STATE_SELECTED]);
-
style = gtk_widget_get_style(w);
if (style == NULL)
return;
if (!gdk_color_equal(&style->text[GTK_STATE_SELECTED], &style->text[GTK_STATE_ACTIVE]))
gtk_widget_modify_text(w, GTK_STATE_ACTIVE, &style->text[GTK_STATE_SELECTED]);
-}
#endif
+}
void ListBoxX::Create(Window &, int, Point, int, bool) {
wid = gtk_window_new(GTK_WINDOW_POPUP);
@@ -2115,21 +2356,6 @@ void ListBoxX::Create(Window &, int, Point, int, bool) {
gtk_container_add(GTK_CONTAINER(frame), PWidget(scroller));
gtk_widget_show(PWidget(scroller));
-#if GTK_MAJOR_VERSION < 2
- list = gtk_clist_new(1);
- GtkWidget *wid = PWidget(list); // No code inside the GTK_OBJECT macro
- gtk_widget_show(wid);
- gtk_container_add(GTK_CONTAINER(PWidget(scroller)), wid);
- gtk_clist_set_column_auto_resize(GTK_CLIST(wid), 0, TRUE);
- gtk_clist_set_selection_mode(GTK_CLIST(wid), GTK_SELECTION_BROWSE);
- gtk_signal_connect(GTK_OBJECT(wid), "unselect_row",
- GTK_SIGNAL_FUNC(UnselectionAC), ¤t);
- gtk_signal_connect(GTK_OBJECT(wid), "select_row",
- GTK_SIGNAL_FUNC(SelectionAC), ¤t);
- gtk_signal_connect(GTK_OBJECT(wid), "button_press_event",
- GTK_SIGNAL_FUNC(ButtonPress), this);
- gtk_clist_set_shadow_type(GTK_CLIST(wid), GTK_SHADOW_NONE);
-#else
/* Tree and its model */
GtkListStore *store =
gtk_list_store_new(N_COLUMNS, GDK_TYPE_PIXBUF, G_TYPE_STRING);
@@ -2153,7 +2379,7 @@ void ListBoxX::Create(Window &, int, Point, int, bool) {
gtk_tree_view_column_pack_start(column, pixbuf_renderer, FALSE);
gtk_tree_view_column_add_attribute(column, pixbuf_renderer,
"pixbuf", PIXBUF_COLUMN);
-
+
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
gtk_cell_renderer_text_set_fixed_height_from_font(GTK_CELL_RENDERER_TEXT(renderer), 1);
gtk_tree_view_column_pack_start(column, renderer, TRUE);
@@ -2169,28 +2395,19 @@ void ListBoxX::Create(Window &, int, Point, int, bool) {
gtk_widget_show(wid);
g_signal_connect(G_OBJECT(wid), "button_press_event",
G_CALLBACK(ButtonPress), this);
-#endif
gtk_widget_realize(PWidget(wid));
}
void ListBoxX::SetFont(Font &scint_font) {
-#if GTK_MAJOR_VERSION < 2
- GtkStyle *style = gtk_widget_get_style(GTK_WIDGET(PWidget(list)));
- if (!gdk_font_equal(style->font, PFont(scint_font)->pfont)) {
- style = gtk_style_copy(style);
- gdk_font_unref(style->font);
- style->font = PFont(scint_font)->pfont;
- gdk_font_ref(style->font);
- gtk_widget_set_style(GTK_WIDGET(PWidget(list)), style);
- gtk_style_unref(style);
- }
-#else
// Only do for Pango font as there have been crashes for GDK fonts
if (Created() && PFont(scint_font)->pfd) {
// Current font is Pango font
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_override_font(PWidget(list), PFont(scint_font)->pfd);
+#else
gtk_widget_modify_font(PWidget(list), PFont(scint_font)->pfd);
- }
#endif
+ }
}
void ListBoxX::SetAverageCharWidth(int width) {
@@ -2218,13 +2435,6 @@ PRectangle ListBoxX::GetDesiredRect() {
// First calculate height of the clist for our desired visible
// row count otherwise it tries to expand to the total # of rows
-#if GTK_MAJOR_VERSION < 2
- int ythickness = PWidget(list)->style->klass->ythickness;
- height = (rows * GTK_CLIST(list)->row_height
- + rows + 1
- + 2 * (ythickness
- + GTK_CONTAINER(PWidget(list))->border_width));
-#else
// Get cell height
int row_width=0;
int row_height=0;
@@ -2232,6 +2442,14 @@ PRectangle ListBoxX::GetDesiredRect() {
gtk_tree_view_get_column(GTK_TREE_VIEW(list), 0);
gtk_tree_view_column_cell_get_size(column, NULL,
NULL, NULL, &row_width, &row_height);
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkStyleContext *styleContextList = gtk_widget_get_style_context(PWidget(list));
+ GtkBorder padding;
+ gtk_style_context_get_padding(styleContextList, GTK_STATE_FLAG_NORMAL, &padding);
+ height = (rows * row_height
+ + padding.top + padding.bottom
+ + 2 * (gtk_container_get_border_width(GTK_CONTAINER(PWidget(list))) + 1));
+#else
int ythickness = PWidget(list)->style->ythickness;
height = (rows * row_height
+ 2 * (ythickness
@@ -2240,7 +2458,11 @@ PRectangle ListBoxX::GetDesiredRect() {
gtk_widget_set_size_request(GTK_WIDGET(PWidget(list)), -1, height);
// Get the size of the scroller because we set usize on the window
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_get_preferred_size(GTK_WIDGET(scroller), NULL, &req);
+#else
gtk_widget_size_request(GTK_WIDGET(scroller), &req);
+#endif
rc.right = req.width;
rc.bottom = req.height;
@@ -2256,30 +2478,19 @@ PRectangle ListBoxX::GetDesiredRect() {
}
int ListBoxX::CaretFromEdge() {
-#if GTK_MAJOR_VERSION >= 2
gint renderer_width, renderer_height;
gtk_cell_renderer_get_fixed_size(pixbuf_renderer, &renderer_width,
&renderer_height);
return 4 + renderer_width;
-#endif
- return 4 + xset.GetWidth();
}
void ListBoxX::Clear() {
-#if GTK_MAJOR_VERSION < 2
- gtk_clist_clear(GTK_CLIST(list));
-#else
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
gtk_list_store_clear(GTK_LIST_STORE(model));
-#endif
maxItemCharacters = 0;
}
-#if GTK_MAJOR_VERSION < 2
-static void init_pixmap(ListImage *list_image, GtkWidget *window) {
-#else
static void init_pixmap(ListImage *list_image) {
-#endif
const char *textForm = list_image->xpm_data;
const char * const * xpm_lineform = reinterpret_cast<const char * const *>(textForm);
const char **xpm_lineformfromtext = 0;
@@ -2294,28 +2505,10 @@ static void init_pixmap(ListImage *list_image) {
}
// Drop any existing pixmap/bitmap as data may have changed
-#if GTK_MAJOR_VERSION < 2
- if (list_image->pixmap)
- gdk_pixmap_unref(list_image->pixmap);
- list_image->pixmap = NULL;
- if (list_image->bitmap)
- gdk_bitmap_unref(list_image->bitmap);
- list_image->bitmap = NULL;
-
- list_image->pixmap = gdk_pixmap_colormap_create_from_xpm_d(NULL
- , gtk_widget_get_colormap(window), &(list_image->bitmap), NULL
- , (gchar **) xpm_lineform);
- if (NULL == list_image->pixmap) {
- if (list_image->bitmap)
- gdk_bitmap_unref(list_image->bitmap);
- list_image->bitmap = NULL;
- }
-#else
if (list_image->pixbuf)
g_object_unref(list_image->pixbuf);
list_image->pixbuf =
gdk_pixbuf_new_from_xpm_data((const gchar**)xpm_lineform);
-#endif
delete []xpm_lineformfromtext;
}
@@ -2327,16 +2520,6 @@ void ListBoxX::Append(char *s, int type) {
list_image = (ListImage *) g_hash_table_lookup((GHashTable *) pixhash
, (gconstpointer) GINT_TO_POINTER(type));
}
-#if GTK_MAJOR_VERSION < 2
- char * szs[] = { s, NULL };
- int rownum = gtk_clist_append(GTK_CLIST(list), szs);
- if (list_image) {
- if (NULL == list_image->pixmap)
- init_pixmap(list_image, (GtkWidget *) list);
- gtk_clist_set_pixtext(GTK_CLIST(list), rownum, 0, s, SPACING
- , list_image->pixmap, list_image->bitmap);
- }
-#else
GtkTreeIter iter;
GtkListStore *store =
GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(list)));
@@ -2351,7 +2534,7 @@ void ListBoxX::Append(char *s, int type) {
gint pixbuf_width = gdk_pixbuf_get_width(list_image->pixbuf);
gint renderer_height, renderer_width;
- gtk_cell_renderer_get_fixed_size(pixbuf_renderer,
+ gtk_cell_renderer_get_fixed_size(pixbuf_renderer,
&renderer_width, &renderer_height);
if (pixbuf_width > renderer_width)
gtk_cell_renderer_set_fixed_size(pixbuf_renderer,
@@ -2364,7 +2547,6 @@ void ListBoxX::Append(char *s, int type) {
gtk_list_store_set(GTK_LIST_STORE(store), &iter,
TEXT_COLUMN, s, -1);
}
-#endif
size_t len = strlen(s);
if (maxItemCharacters < len)
maxItemCharacters = len;
@@ -2372,24 +2554,12 @@ void ListBoxX::Append(char *s, int type) {
int ListBoxX::Length() {
if (wid)
-#if GTK_MAJOR_VERSION < 2
- return GTK_CLIST(list)->rows;
-#else
return gtk_tree_model_iter_n_children(gtk_tree_view_get_model
(GTK_TREE_VIEW(list)), NULL);
-#endif
return 0;
}
void ListBoxX::Select(int n) {
-#if GTK_MAJOR_VERSION < 2
- if (n == -1) {
- gtk_clist_unselect_row(GTK_CLIST(list), current, 0);
- } else {
- gtk_clist_select_row(GTK_CLIST(list), n, 0);
- gtk_clist_moveto(GTK_CLIST(list), n, 0, 0.5, 0.5);
- }
-#else
GtkTreeIter iter;
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
GtkTreeSelection *selection =
@@ -2406,11 +2576,17 @@ void ListBoxX::Select(int n) {
// Move the scrollbar to show the selection.
int total = Length();
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkAdjustment *adj =
+ gtk_scrollable_get_vadjustment(GTK_SCROLLABLE(list));
+ gfloat value = ((gfloat)n / total) * (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_lower(adj))
+ + gtk_adjustment_get_lower(adj) - gtk_adjustment_get_page_size(adj) / 2;
+#else
GtkAdjustment *adj =
gtk_tree_view_get_vadjustment(GTK_TREE_VIEW(list));
gfloat value = ((gfloat)n / total) * (adj->upper - adj->lower)
+ adj->lower - adj->page_size / 2;
-
+#endif
// Get cell height
int row_width;
int row_height;
@@ -2429,21 +2605,22 @@ void ListBoxX::Select(int n) {
}
// Clamp it.
value = (value < 0)? 0 : value;
+#if GTK_CHECK_VERSION(3,0,0)
+ value = (value > (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)))?
+ (gtk_adjustment_get_upper(adj) - gtk_adjustment_get_page_size(adj)) : value;
+#else
value = (value > (adj->upper - adj->page_size))?
(adj->upper - adj->page_size) : value;
+#endif
// Set it.
gtk_adjustment_set_value(adj, value);
} else {
gtk_tree_selection_unselect_all(selection);
}
-#endif
}
int ListBoxX::GetSelection() {
-#if GTK_MAJOR_VERSION < 2
- return current;
-#else
GtkTreeIter iter;
GtkTreeModel *model;
GtkTreeSelection *selection;
@@ -2456,20 +2633,9 @@ int ListBoxX::GetSelection() {
return indices[0];
}
return -1;
-#endif
}
int ListBoxX::Find(const char *prefix) {
-#if GTK_MAJOR_VERSION < 2
- int count = Length();
- for (int i = 0; i < count; i++) {
- char *s = 0;
- gtk_clist_get_text(GTK_CLIST(list), i, 0, &s);
- if (s && (0 == strncmp(prefix, s, strlen(prefix)))) {
- return i;
- }
- }
-#else
GtkTreeIter iter;
GtkTreeModel *model =
gtk_tree_view_get_model(GTK_TREE_VIEW(list));
@@ -2479,43 +2645,31 @@ int ListBoxX::Find(const char *prefix) {
gchar *s;
gtk_tree_model_get(model, &iter, TEXT_COLUMN, &s, -1);
if (s && (0 == strncmp(prefix, s, strlen(prefix)))) {
+ g_free(s);
return i;
}
+ g_free(s);
valid = gtk_tree_model_iter_next(model, &iter) != FALSE;
i++;
}
-#endif
return -1;
}
void ListBoxX::GetValue(int n, char *value, int len) {
char *text = NULL;
-#if GTK_MAJOR_VERSION < 2
- GtkCellType type = gtk_clist_get_cell_type(GTK_CLIST(list), n, 0);
- switch (type) {
- case GTK_CELL_TEXT:
- gtk_clist_get_text(GTK_CLIST(list), n, 0, &text);
- break;
- case GTK_CELL_PIXTEXT:
- gtk_clist_get_pixtext(GTK_CLIST(list), n, 0, &text, NULL, NULL, NULL);
- break;
- default:
- break;
- }
-#else
GtkTreeIter iter;
GtkTreeModel *model = gtk_tree_view_get_model(GTK_TREE_VIEW(list));
bool valid = gtk_tree_model_iter_nth_child(model, &iter, NULL, n) != FALSE;
if (valid) {
gtk_tree_model_get(model, &iter, TEXT_COLUMN, &text, -1);
}
-#endif
if (text && len > 0) {
strncpy(value, text, len);
value[len - 1] = '\0';
} else {
value[0] = '\0';
}
+ g_free(text);
}
// g_return_if_fail causes unnecessary compiler warning in release compile.
@@ -2538,18 +2692,9 @@ void ListBoxX::RegisterImage(int type, const char *xpm_data) {
(gconstpointer) GINT_TO_POINTER(type));
if (list_image) {
// Drop icon already registered
-#if GTK_MAJOR_VERSION < 2
- if (list_image->pixmap)
- gdk_pixmap_unref(list_image->pixmap);
- list_image->pixmap = 0;
- if (list_image->bitmap)
- gdk_bitmap_unref(list_image->bitmap);
- list_image->bitmap = 0;
-#else
if (list_image->pixbuf)
g_object_unref(list_image->pixbuf);
list_image->pixbuf = NULL;
-#endif
list_image->xpm_data = xpm_data;
} else {
list_image = g_new0(ListImage, 1);
@@ -2597,39 +2742,47 @@ Menu::Menu() : mid(0) {}
void Menu::CreatePopUp() {
Destroy();
- mid = gtk_item_factory_new(GTK_TYPE_MENU, "<main>", NULL);
+ mid = gtk_menu_new();
+#if GLIB_CHECK_VERSION(2,10,0)
+ g_object_ref_sink(G_OBJECT(mid));
+#else
+ g_object_ref(G_OBJECT(mid));
+ gtk_object_sink(GTK_OBJECT(G_OBJECT(mid)));
+#endif
}
void Menu::Destroy() {
if (mid)
-#if GTK_MAJOR_VERSION < 2
- gtk_object_unref(GTK_OBJECT(mid));
-#else
g_object_unref(G_OBJECT(mid));
-#endif
mid = 0;
}
+static void MenuPositionFunc(GtkMenu *, gint *x, gint *y, gboolean *, gpointer userData) {
+ sptr_t intFromPointer = reinterpret_cast<sptr_t>(userData);
+ *x = intFromPointer & 0xffff;
+ *y = intFromPointer >> 16;
+}
+
void Menu::Show(Point pt, Window &) {
int screenHeight = gdk_screen_height();
int screenWidth = gdk_screen_width();
- GtkItemFactory *factory = reinterpret_cast<GtkItemFactory *>(mid);
- GtkWidget *widget = gtk_item_factory_get_widget(factory, "<main>");
- gtk_widget_show_all(widget);
+ GtkMenu *widget = reinterpret_cast<GtkMenu *>(mid);
+ gtk_widget_show_all(GTK_WIDGET(widget));
GtkRequisition requisition;
- gtk_widget_size_request(widget, &requisition);
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_get_preferred_size(GTK_WIDGET(widget), NULL, &requisition);
+#else
+ gtk_widget_size_request(GTK_WIDGET(widget), &requisition);
+#endif
if ((pt.x + requisition.width) > screenWidth) {
pt.x = screenWidth - requisition.width;
}
if ((pt.y + requisition.height) > screenHeight) {
pt.y = screenHeight - requisition.height;
}
-#if GTK_MAJOR_VERSION >= 2
- gtk_item_factory_popup(factory, pt.x - 4, pt.y - 4, 3,
+ gtk_menu_popup(widget, NULL, NULL, MenuPositionFunc,
+ reinterpret_cast<void *>((pt.y << 16) | pt.x), 0,
gtk_get_current_event_time());
-#else
- gtk_item_factory_popup(factory, pt.x - 4, pt.y - 4, 3, 0);
-#endif
}
ElapsedTime::ElapsedTime() {
@@ -2701,11 +2854,7 @@ const char *Platform::DefaultFont() {
#ifdef G_OS_WIN32
return "Lucida Console";
#else
-#ifdef USE_PANGO
return "!Sans";
-#else
- return "lucidatypewriter";
-#endif
#endif
}
diff --git a/plugins/scintilla/scintilla/PositionCache.cxx b/plugins/scintilla/scintilla/PositionCache.cxx
index 7bb0106..e59c126 100644
--- a/plugins/scintilla/scintilla/PositionCache.cxx
+++ b/plugins/scintilla/scintilla/PositionCache.cxx
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <ctype.h>
+#include <string>
#include <vector>
#include "Platform.h"
@@ -29,6 +30,7 @@
#include "ViewStyle.h"
#include "CharClassify.h"
#include "Decoration.h"
+#include "ILexer.h"
#include "Document.h"
#include "Selection.h"
#include "PositionCache.h"
@@ -66,6 +68,8 @@ LineLayout::LineLayout(int maxLineLength_) :
widthLine(wrapWidthInfinite),
lines(1),
wrapIndent(0) {
+ bracePreviousStyles[0] = 0;
+ bracePreviousStyles[1] = 0;
Resize(maxLineLength_);
}
@@ -147,15 +151,15 @@ void LineLayout::SetLineStart(int line, int start) {
}
void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
- char bracesMatchStyle, int xHighlight) {
- if (rangeLine.ContainsCharacter(braces[0])) {
+ char bracesMatchStyle, int xHighlight, bool ignoreStyle) {
+ if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[0] = styles[braceOffset];
styles[braceOffset] = bracesMatchStyle;
}
}
- if (rangeLine.ContainsCharacter(braces[1])) {
+ if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
bracePreviousStyles[1] = styles[braceOffset];
@@ -168,14 +172,14 @@ void LineLayout::SetBracesHighlight(Range rangeLine, Position braces[],
}
}
-void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[]) {
- if (rangeLine.ContainsCharacter(braces[0])) {
+void LineLayout::RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle) {
+ if (!ignoreStyle && rangeLine.ContainsCharacter(braces[0])) {
int braceOffset = braces[0] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[0];
}
}
- if (rangeLine.ContainsCharacter(braces[1])) {
+ if (!ignoreStyle && rangeLine.ContainsCharacter(braces[1])) {
int braceOffset = braces[1] - rangeLine.start;
if (braceOffset < numCharsInLine) {
styles[braceOffset] = bracePreviousStyles[1];
@@ -361,7 +365,8 @@ void BreakFinder::Insert(int val) {
for (unsigned int j = 0; j<saeLen; j++) {
if (val == selAndEdge[j]) {
return;
- } if (val < selAndEdge[j]) {
+ }
+ if (val < selAndEdge[j]) {
for (unsigned int k = saeLen; k>j; k--) {
selAndEdge[k] = selAndEdge[k-1];
}
@@ -386,18 +391,19 @@ static int NextBadU(const char *s, int p, int len, int &trailBytes) {
return -1;
}
-BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection) :
+BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
+ int xStart, bool breakForSelection, Document *pdoc_) :
ll(ll_),
lineStart(lineStart_),
lineEnd(lineEnd_),
posLineStart(posLineStart_),
- utf8(utf8_),
nextBreak(lineStart_),
saeSize(0),
saeLen(0),
saeCurrentPos(0),
saeNext(0),
- subBreak(-1) {
+ subBreak(-1),
+ pdoc(pdoc_) {
saeSize = 8;
selAndEdge = new int[saeSize];
for (unsigned int j=0; j < saeSize; j++) {
@@ -430,7 +436,7 @@ BreakFinder::BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posL
Insert(ll->edgeColumn - 1);
Insert(lineEnd - 1);
- if (utf8) {
+ if (pdoc && (SC_CP_UTF8 == pdoc->dbcsCodePage)) {
int trailBytes=0;
for (int pos = -1;;) {
pos = NextBadU(ll->chars, pos, lineEnd, trailBytes);
@@ -447,14 +453,10 @@ BreakFinder::~BreakFinder() {
delete []selAndEdge;
}
-int BreakFinder::First() {
+int BreakFinder::First() const {
return nextBreak;
}
-static bool IsTrailByte(int ch) {
- return (ch >= 0x80) && (ch < (0x80 + 0x40));
-}
-
int BreakFinder::Next() {
if (subBreak == -1) {
int prev = nextBreak;
@@ -485,34 +487,7 @@ int BreakFinder::Next() {
subBreak = -1;
return nextBreak;
} else {
- int lastGoodBreak = -1;
- int lastOKBreak = -1;
- int lastUTF8Break = -1;
- int j;
- for (j = subBreak + 1; j <= nextBreak; j++) {
- if (IsSpaceOrTab(ll->chars[j - 1]) && !IsSpaceOrTab(ll->chars[j])) {
- lastGoodBreak = j;
- }
- if (static_cast<unsigned char>(ll->chars[j]) < 'A') {
- lastOKBreak = j;
- }
- if (utf8 && !IsTrailByte(static_cast<unsigned char>(ll->chars[j]))) {
- lastUTF8Break = j;
- }
- if (((j - subBreak) >= lengthEachSubdivision) &&
- ((lastGoodBreak >= 0) || (lastOKBreak >= 0) || (lastUTF8Break >= 0))) {
- break;
- }
- }
- if (lastGoodBreak >= 0) {
- subBreak = lastGoodBreak;
- } else if (lastOKBreak >= 0) {
- subBreak = lastOKBreak;
- } else if (lastUTF8Break >= 0) {
- subBreak = lastUTF8Break;
- } else {
- subBreak = nextBreak;
- }
+ subBreak += pdoc->SafeSegment(ll->chars + subBreak, nextBreak-subBreak, lengthEachSubdivision);
if (subBreak >= nextBreak) {
subBreak = -1;
return nextBreak;
@@ -534,7 +509,7 @@ void PositionCacheEntry::Set(unsigned int styleNumber_, const char *s_,
clock = clock_;
if (s_ && positions_) {
positions = new short[len + (len + 1) / 2];
- for (unsigned int i=0;i<len;i++) {
+ for (unsigned int i=0; i<len; i++) {
positions[i] = static_cast<short>(positions_[i]);
}
memcpy(reinterpret_cast<char *>(positions + len), s_, len);
@@ -557,7 +532,7 @@ bool PositionCacheEntry::Retrieve(unsigned int styleNumber_, const char *s_,
unsigned int len_, int *positions_) const {
if ((styleNumber == styleNumber_) && (len == len_) &&
(memcmp(reinterpret_cast<char *>(positions + len), s_, len)== 0)) {
- for (unsigned int i=0;i<len;i++) {
+ for (unsigned int i=0; i<len; i++) {
positions_[i] = positions[i];
}
return true;
@@ -579,7 +554,7 @@ int PositionCacheEntry::Hash(unsigned int styleNumber, const char *s, unsigned i
return ret;
}
-bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) {
+bool PositionCacheEntry::NewerThan(const PositionCacheEntry &other) const {
return clock > other.clock;
}
@@ -603,7 +578,7 @@ PositionCache::~PositionCache() {
void PositionCache::Clear() {
if (!allClear) {
- for (size_t i=0;i<size;i++) {
+ for (size_t i=0; i<size; i++) {
pces[i].Clear();
}
}
@@ -619,7 +594,8 @@ void PositionCache::SetSize(size_t size_) {
}
void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
- const char *s, unsigned int len, int *positions) {
+ const char *s, unsigned int len, int *positions, Document *pdoc) {
+
allClear = false;
int probe = -1;
if ((size > 0) && (len < 30)) {
@@ -641,13 +617,28 @@ void PositionCache::MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned
probe = probe2;
}
}
- surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
+ if (len > BreakFinder::lengthStartSubdivision) {
+ // Break up into segments
+ unsigned int startSegment = 0;
+ int xStartSegment = 0;
+ while (startSegment < len) {
+ unsigned int lenSegment = pdoc->SafeSegment(s + startSegment, len - startSegment, BreakFinder::lengthEachSubdivision);
+ surface->MeasureWidths(vstyle.styles[styleNumber].font, s + startSegment, lenSegment, positions + startSegment);
+ for (unsigned int inSeg = 0; inSeg < lenSegment; inSeg++) {
+ positions[startSegment + inSeg] += xStartSegment;
+ }
+ xStartSegment = positions[startSegment + lenSegment - 1];
+ startSegment += lenSegment;
+ }
+ } else {
+ surface->MeasureWidths(vstyle.styles[styleNumber].font, s, len, positions);
+ }
if (probe >= 0) {
clock++;
if (clock > 60000) {
// Since there are only 16 bits for the clock, wrap it round and
// reset all cache entries so none get stuck with a high clock.
- for (size_t i=0;i<size;i++) {
+ for (size_t i=0; i<size; i++) {
pces[i].ResetClock();
}
clock = 2;
diff --git a/plugins/scintilla/scintilla/PositionCache.h b/plugins/scintilla/scintilla/PositionCache.h
index e99ae58..6abec6e 100644
--- a/plugins/scintilla/scintilla/PositionCache.h
+++ b/plugins/scintilla/scintilla/PositionCache.h
@@ -63,8 +63,8 @@ public:
bool InLine(int offset, int line) const;
void SetLineStart(int line, int start);
void SetBracesHighlight(Range rangeLine, Position braces[],
- char bracesMatchStyle, int xHighlight);
- void RestoreBracesHighlight(Range rangeLine, Position braces[]);
+ char bracesMatchStyle, int xHighlight, bool ignoreStyle);
+ void RestoreBracesHighlight(Range rangeLine, Position braces[], bool ignoreStyle);
int FindBefore(int x, int lower, int upper) const;
int EndLineStyle() const;
};
@@ -93,7 +93,7 @@ public:
};
void Invalidate(LineLayout::validLevel validity_);
void SetLevel(int level_);
- int GetLevel() { return level; }
+ int GetLevel() const { return level; }
LineLayout *Retrieve(int lineNumber, int lineCaret, int maxChars, int styleClock_,
int linesOnScreen, int linesInDoc);
void Dispose(LineLayout *ll);
@@ -111,22 +111,16 @@ public:
void Clear();
bool Retrieve(unsigned int styleNumber_, const char *s_, unsigned int len_, int *positions_) const;
static int Hash(unsigned int styleNumber, const char *s, unsigned int len);
- bool NewerThan(const PositionCacheEntry &other);
+ bool NewerThan(const PositionCacheEntry &other) const;
void ResetClock();
};
// Class to break a line of text into shorter runs at sensible places.
class BreakFinder {
- // If a whole run is longer than lengthStartSubdivision then subdivide
- // into smaller runs at spaces or punctuation.
- enum { lengthStartSubdivision = 300 };
- // Try to make each subdivided run lengthEachSubdivision or shorter.
- enum { lengthEachSubdivision = 100 };
LineLayout *ll;
int lineStart;
int lineEnd;
int posLineStart;
- bool utf8;
int nextBreak;
int *selAndEdge;
unsigned int saeSize;
@@ -134,11 +128,18 @@ class BreakFinder {
unsigned int saeCurrentPos;
int saeNext;
int subBreak;
+ Document *pdoc;
void Insert(int val);
public:
- BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_, bool utf8_, int xStart, bool breakForSelection);
+ // If a whole run is longer than lengthStartSubdivision then subdivide
+ // into smaller runs at spaces or punctuation.
+ enum { lengthStartSubdivision = 300 };
+ // Try to make each subdivided run lengthEachSubdivision or shorter.
+ enum { lengthEachSubdivision = 100 };
+ BreakFinder(LineLayout *ll_, int lineStart_, int lineEnd_, int posLineStart_,
+ int xStart, bool breakForSelection, Document *pdoc_);
~BreakFinder();
- int First();
+ int First() const;
int Next();
};
@@ -152,9 +153,9 @@ public:
~PositionCache();
void Clear();
void SetSize(size_t size_);
- int GetSize() { return size; }
+ size_t GetSize() const { return size; }
void MeasureWidths(Surface *surface, ViewStyle &vstyle, unsigned int styleNumber,
- const char *s, unsigned int len, int *positions);
+ const char *s, unsigned int len, int *positions, Document *pdoc);
};
inline bool IsSpaceOrTab(int ch) {
diff --git a/plugins/scintilla/scintilla/PropSet.cxx b/plugins/scintilla/scintilla/PropSetSimple.cxx
similarity index 88%
rename from plugins/scintilla/scintilla/PropSet.cxx
rename to plugins/scintilla/scintilla/PropSetSimple.cxx
index 9936c39..6942f6e 100644
--- a/plugins/scintilla/scintilla/PropSet.cxx
+++ b/plugins/scintilla/scintilla/PropSetSimple.cxx
@@ -1,8 +1,8 @@
// SciTE - Scintilla based Text Editor
-/** @file PropSet.cxx
+/** @file PropSetSimple.cxx
** A Java style properties file module.
**/
-// Copyright 1998-2003 by Neil Hodgson <neilh scintilla org>
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
// Maintain a dictionary of properties
@@ -19,9 +19,6 @@
#include <string>
#include <map>
-#include "Platform.h"
-
-#include "PropSet.h"
#include "PropSetSimple.h"
#ifdef SCI_NAMESPACE
@@ -96,7 +93,7 @@ const char *PropSetSimple::Get(const char *key) const {
// for that, through a recursive function and a simple chain of pointers.
struct VarChain {
- VarChain(const char*var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {}
+ VarChain(const char *var_=NULL, const VarChain *link_=NULL): var(var_), link(link_) {}
bool contains(const char *testVar) const {
return (var && (0 == strcmp(var, testVar)))
@@ -151,18 +148,14 @@ char *PropSetSimple::Expanded(const char *key) const {
return ret;
}
-char *PropSetSimple::ToString() const {
- mapss *props = static_cast<mapss *>(impl);
- std::string sval;
- for (mapss::const_iterator it=props->begin(); it != props->end(); it++) {
- sval += it->first;
- sval += "=";
- sval += it->second;
- sval += "\n";
+int PropSetSimple::GetExpanded(const char *key, char *result) const {
+ char *val = Expanded(key);
+ const int n = strlen(val);
+ if (result) {
+ strcpy(result, val);
}
- char *ret = new char [sval.size() + 1];
- strcpy(ret, sval.c_str());
- return ret;
+ delete []val;
+ return n; // Not including NUL
}
int PropSetSimple::GetInt(const char *key, int defaultValue) const {
diff --git a/plugins/scintilla/scintilla/PropSetSimple.h b/plugins/scintilla/scintilla/PropSetSimple.h
index 1674cfb..b798737 100644
--- a/plugins/scintilla/scintilla/PropSetSimple.h
+++ b/plugins/scintilla/scintilla/PropSetSimple.h
@@ -12,7 +12,7 @@
namespace Scintilla {
#endif
-class PropSetSimple : public PropertyGet {
+class PropSetSimple {
void *impl;
void Set(const char *keyVal);
public:
@@ -22,7 +22,7 @@ public:
void SetMultiple(const char *);
const char *Get(const char *key) const;
char *Expanded(const char *key) const;
- char *ToString() const;
+ int GetExpanded(const char *key, char *result) const;
int GetInt(const char *key, int defaultValue=0) const;
};
diff --git a/plugins/scintilla/scintilla/RESearch.cxx b/plugins/scintilla/scintilla/RESearch.cxx
index 0c40045..f26375f 100644
--- a/plugins/scintilla/scintilla/RESearch.cxx
+++ b/plugins/scintilla/scintilla/RESearch.cxx
@@ -17,6 +17,7 @@
* Put all global/static variables into an object so this code can be
* used from multiple threads, etc.
* Some extensions by Philippe Lhoste PhiLho(a)GMX.net
+ * '?' extensions by Michael Mullin masmullin gmail com
*
* These routines are the PUBLIC DOMAIN equivalents of regex
* routines as found in 4.nBSD UN*X, with minor extensions.
@@ -53,7 +54,7 @@
* Regular Expressions:
*
* [1] char matches itself, unless it is a special
- * character (metachar): . \ [ ] * + ^ $
+ * character (metachar): . \ [ ] * + ? ^ $
* and ( ) if posix option.
*
* [2] . matches any character.
@@ -65,12 +66,12 @@
* regex searches are made line per line
* (stripped of end-of-line chars).
* - if not in posix mode, when followed by a
- * left or right round bracket (see [7]);
- * - when followed by a digit 1 to 9 (see [8]);
+ * left or right round bracket (see [8]);
+ * - when followed by a digit 1 to 9 (see [9]);
* - when followed by a left or right angle bracket
- * (see [9]);
- * - when followed by d, D, s, S, w or W (see [10]);
- * - when followed by x and two hexa digits (see [11].
+ * (see [10]);
+ * - when followed by d, D, s, S, w or W (see [11]);
+ * - when followed by x and two hexa digits (see [12].
* Backslash is used as an escape character for all
* other meta-characters, and itself.
*
@@ -101,23 +102,28 @@
* [a-zA-Z] any alpha
*
* [5] * any regular expression form [1] to [4]
- * (except [7], [8] and [9] forms of [3]),
+ * (except [8], [9] and [10] forms of [3]),
* followed by closure char (*)
* matches zero or more matches of that form.
*
* [6] + same as [5], except it matches one or more.
- * Both [5] and [6] are greedy (they match as much as possible).
*
- * [7] a regular expression in the form [1] to [12], enclosed
+ * [5-6] Both [5] and [6] are greedy (they match as much as possible).
+ * Unless they are followed by the 'lazy' quantifier (?)
+ * In which case both [5] and [6] try to match as little as possible
+ *
+ * [7] ? same as [5] except it matches zero or one.
+ *
+ * [8] a regular expression in the form [1] to [13], enclosed
* as \(form\) (or (form) with posix flag) matches what
* form matches. The enclosure creates a set of tags,
- * used for [8] and for pattern substitution.
+ * used for [9] and for pattern substitution.
* The tagged forms are numbered starting from 1.
*
- * [8] a \ followed by a digit 1 to 9 matches whatever a
- * previously tagged regular expression ([7]) matched.
+ * [9] a \ followed by a digit 1 to 9 matches whatever a
+ * previously tagged regular expression ([8]) matched.
*
- * [9] \< a regular expression starting with a \< construct
+ * [10] \< a regular expression starting with a \< construct
* \> and/or ending with a \> construct, restricts the
* pattern matching to the beginning of a word, and/or
* the end of a word. A word is defined to be a character
@@ -126,7 +132,7 @@
* by user setting. The word must also be preceded and/or
* followed by any character outside those mentioned.
*
- * [10] \l a backslash followed by d, D, s, S, w or W,
+ * [11] \l a backslash followed by d, D, s, S, w or W,
* becomes a character class (both inside and
* outside sets []).
* d: decimal digits
@@ -136,16 +142,16 @@
* w: alphanumeric & underscore (changed by user setting)
* W: any char except alphanumeric & underscore (see above)
*
- * [11] \xHH a backslash followed by x and two hexa digits,
+ * [12] \xHH a backslash followed by x and two hexa digits,
* becomes the character whose Ascii code is equal
* to these digits. If not followed by two digits,
* it is 'x' char itself.
*
- * [12] a composite regular expression xy where x and y
- * are in the form [1] to [11] matches the longest
+ * [13] a composite regular expression xy where x and y
+ * are in the form [1] to [12] matches the longest
* match of x followed by a match for y.
*
- * [13] ^ a regular expression starting with a ^ character
+ * [14] ^ a regular expression starting with a ^ character
* $ and/or ending with a $ character, restricts the
* pattern matching to the beginning of the line,
* or the end of line. [anchors] Elsewhere in the
@@ -226,6 +232,8 @@ using namespace Scintilla;
#define EOW 9
#define REF 10
#define CLO 11
+#define CLQ 12 /* 0 to 1 closure */
+#define LCLO 13 /* lazy closure */
#define END 0
@@ -248,6 +256,7 @@ const char bitarr[] = { 1, 2, 4, 8, 16, 32, 64, '\200' };
*/
RESearch::RESearch(CharClassify *charClassTable) {
+ failure = 0;
charClass = charClassTable;
Init();
}
@@ -355,8 +364,8 @@ static int GetHexaChar(unsigned char hd1, unsigned char hd2) {
* or -1 for a char class. In this case, bittab is changed.
*/
int RESearch::GetBackslashExpression(
- const char *pattern,
- int &incr) {
+ const char *pattern,
+ int &incr) {
// Since error reporting is primitive and messages are not used anyway,
// I choose to interpret unexpected syntax in a logical way instead
// of reporting errors. Otherwise, we can stick on, eg., PCRE behavior.
@@ -521,7 +530,7 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
if (*(p+1) != ']') {
c1 = prevChar + 1;
i++;
- c2 = *++p;
+ c2 = static_cast<unsigned char>(*++p);
if (c2 == '\\') {
if (!*(p+1)) // End of RE
return badpat("Missing ]");
@@ -576,7 +585,7 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
prevChar = -1;
}
} else {
- prevChar = *p;
+ prevChar = static_cast<unsigned char>(*p);
ChSetWithCase(*p, caseSensitive);
}
i++;
@@ -592,10 +601,11 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
case '*': /* match 0 or more... */
case '+': /* match 1 or more... */
+ case '?':
if (p == pattern)
return badpat("Empty closure");
lp = sp; /* previous opcode */
- if (*lp == CLO) /* equivalence... */
+ if (*lp == CLO || *lp == LCLO) /* equivalence... */
break;
switch (*lp) {
@@ -617,9 +627,13 @@ const char *RESearch::Compile(const char *pattern, int length, bool caseSensitiv
*mp++ = END;
*mp++ = END;
sp = mp;
+
while (--mp > lp)
*mp = mp[-1];
- *mp = CLO;
+ if (*p == '?') *mp = CLQ;
+ else if (*(p+1) == '?') *mp = LCLO;
+ else *mp = CLO;
+
mp = sp;
break;
@@ -844,6 +858,7 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
int bp; /* beginning of subpat... */
int ep; /* ending of subpat... */
int are; /* to save the line ptr. */
+ int llp; /* lazy lp for LCLO */
while ((op = *ap++) != END)
switch (op) {
@@ -878,7 +893,7 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
case EOT:
eopat[*ap++] = lp;
break;
- case BOW:
+ case BOW:
if ((lp!=bol && iswordc(ci.CharAt(lp-1))) || !iswordc(ci.CharAt(lp)))
return NOTFOUND;
break;
@@ -894,18 +909,27 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
if (ci.CharAt(bp++) != ci.CharAt(lp++))
return NOTFOUND;
break;
+ case LCLO:
+ case CLQ:
case CLO:
are = lp;
switch (*ap) {
case ANY:
- while (lp < endp)
+ if (op == CLO || op == LCLO)
+ while (lp < endp)
+ lp++;
+ else if (lp < endp)
lp++;
+
n = ANYSKIP;
break;
case CHR:
c = *(ap+1);
- while ((lp < endp) && (c == ci.CharAt(lp)))
+ if (op == CLO || op == LCLO)
+ while ((lp < endp) && (c == ci.CharAt(lp)))
+ lp++;
+ else if ((lp < endp) && (c == ci.CharAt(lp)))
lp++;
n = CHRSKIP;
break;
@@ -919,15 +943,23 @@ int RESearch::PMatch(CharacterIndexer &ci, int lp, int endp, char *ap) {
//re_fail("closure: bad nfa.", *ap);
return NOTFOUND;
}
-
ap += n;
- while (lp >= are) {
- if ((e = PMatch(ci, lp, endp, ap)) != NOTFOUND)
- return e;
- --lp;
+ llp = lp;
+ e = NOTFOUND;
+ while (llp >= are) {
+ int q;
+ if ((q = PMatch(ci, llp, endp, ap)) != NOTFOUND) {
+ e = q;
+ lp = llp;
+ if (op != LCLO) return e;
+ }
+ if (*ap == END) return e;
+ --llp;
}
- return NOTFOUND;
+ if (*ap == EOT)
+ PMatch(ci, lp, endp, ap);
+ return e;
default:
//re_fail("RESearch::Execute: bad nfa.", static_cast<char>(op));
return NOTFOUND;
diff --git a/plugins/scintilla/scintilla/RunStyles.cxx b/plugins/scintilla/scintilla/RunStyles.cxx
index ae32c73..460d5d2 100644
--- a/plugins/scintilla/scintilla/RunStyles.cxx
+++ b/plugins/scintilla/scintilla/RunStyles.cxx
@@ -147,8 +147,10 @@ bool RunStyles::FillRange(int &position, int value, int &fillLength) {
runEnd = RunFromPosition(end);
RemoveRunIfSameAsPrevious(runEnd);
RemoveRunIfSameAsPrevious(runStart);
+ return true;
+ } else {
+ return false;
}
- return true;
}
void RunStyles::SetValueAt(int position, int value) {
diff --git a/plugins/scintilla/scintilla/SVector.h b/plugins/scintilla/scintilla/SVector.h
index 7b92919..12a7d5d 100644
--- a/plugins/scintilla/scintilla/SVector.h
+++ b/plugins/scintilla/scintilla/SVector.h
@@ -19,19 +19,19 @@ namespace Scintilla {
*/
class SVector {
enum { allocSize = 4000 };
-
+
int *v; ///< The vector
unsigned int size; ///< Number of elements allocated
unsigned int len; ///< Number of elements used in vector
-
+
/** Internally allocate more elements than the user wants
* to avoid thrashing the memory allocator. */
void SizeTo(int newSize) {
if (newSize < allocSize)
newSize += allocSize;
- else
+ else
newSize = (newSize * 3) / 2;
- int* newv = new int[newSize];
+ int *newv = new int[newSize];
size = newSize;
unsigned int i=0;
for (; i<len; i++) {
@@ -43,7 +43,7 @@ class SVector {
delete []v;
v = newv;
}
-
+
public:
SVector() {
v = 0;
@@ -60,7 +60,7 @@ public:
size = 0;
if (other.Length() > 0) {
SizeTo(other.Length());
- for (int i=0;i<other.Length();i++)
+ for (int i=0; i<other.Length(); i++)
v[i] = other.v[i];
len = other.Length();
}
@@ -74,7 +74,7 @@ public:
size = 0;
if (other.Length() > 0) {
SizeTo(other.Length());
- for (int i=0;i<other.Length();i++)
+ for (int i=0; i<other.Length(); i++)
v[i] = other.v[i];
len = other.Length();
}
diff --git a/plugins/scintilla/scintilla/ScintillaBase.cxx b/plugins/scintilla/scintilla/ScintillaBase.cxx
index 8b1a048..3de4a45 100644
--- a/plugins/scintilla/scintilla/ScintillaBase.cxx
+++ b/plugins/scintilla/scintilla/ScintillaBase.cxx
@@ -9,19 +9,21 @@
#include <string.h>
#include <stdio.h>
#include <ctype.h>
+#include <assert.h>
+#include <string>
#include <vector>
#include "Platform.h"
+#include "ILexer.h"
#include "Scintilla.h"
-#include "PropSet.h"
+
#include "PropSetSimple.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
-#include "Accessor.h"
-#include "DocumentAccessor.h"
-#include "KeyWords.h"
+#include "LexerModule.h"
+#include "Catalogue.h"
#endif
#include "SplitVector.h"
#include "Partitioning.h"
@@ -52,21 +54,9 @@ ScintillaBase::ScintillaBase() {
displayPopupMenu = true;
listType = 0;
maxListWidth = 0;
-#ifdef SCI_LEXER
- lexLanguage = SCLEX_CONTAINER;
- performingStyle = false;
- lexCurrent = 0;
- for (int wl = 0;wl < numWordLists;wl++)
- keyWordLists[wl] = new WordList;
- keyWordLists[numWordLists] = 0;
-#endif
}
ScintillaBase::~ScintillaBase() {
-#ifdef SCI_LEXER
- for (int wl = 0;wl < numWordLists;wl++)
- delete keyWordLists[wl];
-#endif
}
void ScintillaBase::Finalise() {
@@ -145,16 +135,16 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
AutoCompleteMove(1);
return 0;
case SCI_LINEUP:
- AutoCompleteMove( -1);
+ AutoCompleteMove(-1);
return 0;
case SCI_PAGEDOWN:
AutoCompleteMove(5);
return 0;
case SCI_PAGEUP:
- AutoCompleteMove( -5);
+ AutoCompleteMove(-5);
return 0;
case SCI_VCHOME:
- AutoCompleteMove( -5000);
+ AutoCompleteMove(-5000);
return 0;
case SCI_LINEEND:
AutoCompleteMove(5000);
@@ -202,8 +192,8 @@ int ScintillaBase::KeyCommand(unsigned int iMessage) {
return Editor::KeyCommand(iMessage);
}
-void ScintillaBase::AutoCompleteDoubleClick(void* p) {
- ScintillaBase* sci = reinterpret_cast<ScintillaBase*>(p);
+void ScintillaBase::AutoCompleteDoubleClick(void *p) {
+ ScintillaBase *sci = reinterpret_cast<ScintillaBase *>(p);
sci->AutoCompleteCompleted();
}
@@ -359,6 +349,7 @@ void ScintillaBase::AutoCompleteCompleted() {
scn.wParam = listType;
scn.listType = listType;
Position firstPos = ac.posStart - ac.startLen;
+ scn.position = firstPos;
scn.lParam = firstPos;
scn.text = selected;
NotifyParent(scn);
@@ -384,6 +375,7 @@ void ScintillaBase::AutoCompleteCompleted() {
pdoc->InsertCString(firstPos, selected);
SetEmptySelection(firstPos + static_cast<int>(strlen(selected)));
}
+ SetLastXChosen();
}
int ScintillaBase::AutoCompleteGetCurrent() {
@@ -476,76 +468,194 @@ void ScintillaBase::ButtonDown(Point pt, unsigned int curTime, bool shift, bool
}
#ifdef SCI_LEXER
-void ScintillaBase::SetLexer(uptr_t wParam) {
- lexLanguage = wParam;
- lexCurrent = LexerModule::Find(lexLanguage);
- if (!lexCurrent)
- lexCurrent = LexerModule::Find(SCLEX_NULL);
- int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
- vs.EnsureStyle((1 << bits) - 1);
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+class LexState : public LexInterface {
+ const LexerModule *lexCurrent;
+ void SetLexerModule(const LexerModule *lex);
+ PropSetSimple props;
+public:
+ int lexLanguage;
+
+ LexState(Document *pdoc_);
+ virtual ~LexState();
+ void SetLexer(uptr_t wParam);
+ void SetLexerLanguage(const char *languageName);
+ const char *DescribeWordListSets();
+ void SetWordList(int n, const char *wl);
+ int GetStyleBitsNeeded() const;
+ const char *GetName() const;
+ void *PrivateCall(int operation, void *pointer);
+ const char *PropertyNames();
+ int PropertyType(const char *name);
+ const char *DescribeProperty(const char *name);
+ void PropSet(const char *key, const char *val);
+ const char *PropGet(const char *key) const;
+ int PropGetInt(const char *key, int defaultValue=0) const;
+ int PropGetExpanded(const char *key, char *result) const;
+};
+
+#ifdef SCI_NAMESPACE
}
+#endif
-void ScintillaBase::SetLexerLanguage(const char *languageName) {
+LexState::LexState(Document *pdoc_) : LexInterface(pdoc_) {
+ lexCurrent = 0;
+ performingStyle = false;
lexLanguage = SCLEX_CONTAINER;
- lexCurrent = LexerModule::Find(languageName);
- if (!lexCurrent)
- lexCurrent = LexerModule::Find(SCLEX_NULL);
- if (lexCurrent)
- lexLanguage = lexCurrent->GetLanguage();
- int bits = lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
- vs.EnsureStyle((1 << bits) - 1);
}
-void ScintillaBase::Colourise(int start, int end) {
- if (!performingStyle) {
- // Protect against reentrance, which may occur, for example, when
- // fold points are discovered while performing styling and the folding
- // code looks for child lines which may trigger styling.
- performingStyle = true;
+LexState::~LexState() {
+ if (instance) {
+ instance->Release();
+ instance = 0;
+ }
+}
- int lengthDoc = pdoc->Length();
- if (end == -1)
- end = lengthDoc;
- int len = end - start;
+LexState *ScintillaBase::DocumentLexState() {
+ if (!pdoc->pli) {
+ pdoc->pli = new LexState(pdoc);
+ }
+ return static_cast<LexState *>(pdoc->pli);
+}
+
+void LexState::SetLexerModule(const LexerModule *lex) {
+ if (lex != lexCurrent) {
+ if (instance) {
+ instance->Release();
+ instance = 0;
+ }
+ lexCurrent = lex;
+ if (lexCurrent)
+ instance = lexCurrent->Create();
+ pdoc->LexerChanged();
+ }
+}
- PLATFORM_ASSERT(len >= 0);
- PLATFORM_ASSERT(start + len <= lengthDoc);
+void LexState::SetLexer(uptr_t wParam) {
+ lexLanguage = wParam;
+ if (lexLanguage == SCLEX_CONTAINER) {
+ SetLexerModule(0);
+ } else {
+ const LexerModule *lex = Catalogue::Find(lexLanguage);
+ if (!lex)
+ lex = Catalogue::Find(SCLEX_NULL);
+ SetLexerModule(lex);
+ }
+}
- //WindowAccessor styler(wMain.GetID(), props);
- DocumentAccessor styler(pdoc, props, wMain.GetID());
+void LexState::SetLexerLanguage(const char *languageName) {
+ const LexerModule *lex = Catalogue::Find(languageName);
+ if (!lex)
+ lex = Catalogue::Find(SCLEX_NULL);
+ if (lex)
+ lexLanguage = lex->GetLanguage();
+ SetLexerModule(lex);
+}
- int styleStart = 0;
- if (start > 0)
- styleStart = styler.StyleAt(start - 1) & pdoc->stylingBitsMask;
- styler.SetCodePage(pdoc->dbcsCodePage);
+const char *LexState::DescribeWordListSets() {
+ if (instance) {
+ return instance->DescribeWordListSets();
+ } else {
+ return 0;
+ }
+}
- if (lexCurrent && (len > 0)) { // Should always succeed as null lexer should always be available
- lexCurrent->Lex(start, len, styleStart, keyWordLists, styler);
- styler.Flush();
- if (styler.GetPropertyInt("fold")) {
- lexCurrent->Fold(start, len, styleStart, keyWordLists, styler);
- styler.Flush();
- }
+void LexState::SetWordList(int n, const char *wl) {
+ if (instance) {
+ int firstModification = instance->WordListSet(n, wl);
+ if (firstModification >= 0) {
+ pdoc->ModifiedAt(firstModification);
}
+ }
+}
+
+int LexState::GetStyleBitsNeeded() const {
+ return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+}
- performingStyle = false;
+const char *LexState::GetName() const {
+ return lexCurrent ? lexCurrent->languageName : "";
+}
+
+void *LexState::PrivateCall(int operation, void *pointer) {
+ if (pdoc && instance) {
+ return instance->PrivateCall(operation, pointer);
+ } else {
+ return 0;
+ }
+}
+
+const char *LexState::PropertyNames() {
+ if (instance) {
+ return instance->PropertyNames();
+ } else {
+ return 0;
+ }
+}
+
+int LexState::PropertyType(const char *name) {
+ if (instance) {
+ return instance->PropertyType(name);
+ } else {
+ return SC_TYPE_BOOLEAN;
+ }
+}
+
+const char *LexState::DescribeProperty(const char *name) {
+ if (instance) {
+ return instance->DescribeProperty(name);
+ } else {
+ return 0;
}
}
+
+void LexState::PropSet(const char *key, const char *val) {
+ props.Set(key, val);
+ if (instance) {
+ int firstModification = instance->PropertySet(key, val);
+ if (firstModification >= 0) {
+ pdoc->ModifiedAt(firstModification);
+ }
+ }
+}
+
+const char *LexState::PropGet(const char *key) const {
+ return props.Get(key);
+}
+
+int LexState::PropGetInt(const char *key, int defaultValue) const {
+ return props.GetInt(key, defaultValue);
+}
+
+int LexState::PropGetExpanded(const char *key, char *result) const {
+ return props.GetExpanded(key, result);
+}
+
#endif
void ScintillaBase::NotifyStyleToNeeded(int endStyleNeeded) {
#ifdef SCI_LEXER
- if (lexLanguage != SCLEX_CONTAINER) {
- int endStyled = WndProc(SCI_GETENDSTYLED, 0, 0);
- int lineEndStyled = WndProc(SCI_LINEFROMPOSITION, endStyled, 0);
- endStyled = WndProc(SCI_POSITIONFROMLINE, lineEndStyled, 0);
- Colourise(endStyled, endStyleNeeded);
+ if (DocumentLexState()->lexLanguage != SCLEX_CONTAINER) {
+ int lineEndStyled = pdoc->LineFromPosition(pdoc->GetEndStyled());
+ int endStyled = pdoc->LineStart(lineEndStyled);
+ DocumentLexState()->Colourise(endStyled, endStyleNeeded);
return;
}
#endif
Editor::NotifyStyleToNeeded(endStyleNeeded);
}
+void ScintillaBase::NotifyLexerChanged(Document *, void *) {
+#ifdef SCI_LEXER
+ int bits = DocumentLexState()->GetStyleBitsNeeded();
+ vs.EnsureStyle((1 << bits) - 1);
+#endif
+}
+
sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
switch (iMessage) {
case SCI_AUTOCSHOW:
@@ -708,61 +818,66 @@ sptr_t ScintillaBase::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lPara
#ifdef SCI_LEXER
case SCI_SETLEXER:
- SetLexer(wParam);
- lexLanguage = wParam;
+ DocumentLexState()->SetLexer(wParam);
break;
case SCI_GETLEXER:
- return lexLanguage;
+ return DocumentLexState()->lexLanguage;
case SCI_COLOURISE:
- if (lexLanguage == SCLEX_CONTAINER) {
+ if (DocumentLexState()->lexLanguage == SCLEX_CONTAINER) {
pdoc->ModifiedAt(wParam);
NotifyStyleToNeeded((lParam == -1) ? pdoc->Length() : lParam);
} else {
- Colourise(wParam, lParam);
+ DocumentLexState()->Colourise(wParam, lParam);
}
Redraw();
break;
case SCI_SETPROPERTY:
- props.Set(reinterpret_cast<const char *>(wParam),
+ DocumentLexState()->PropSet(reinterpret_cast<const char *>(wParam),
reinterpret_cast<const char *>(lParam));
break;
case SCI_GETPROPERTY:
- return StringResult(lParam, props.Get(reinterpret_cast<const char *>(wParam)));
-
- case SCI_GETPROPERTYEXPANDED: {
- char *val = props.Expanded(reinterpret_cast<const char *>(wParam));
- const int n = strlen(val);
- if (lParam != 0) {
- char *ptr = reinterpret_cast<char *>(lParam);
- strcpy(ptr, val);
- }
- delete []val;
- return n; // Not including NUL
- }
+ return StringResult(lParam, DocumentLexState()->PropGet(reinterpret_cast<const char *>(wParam)));
+
+ case SCI_GETPROPERTYEXPANDED:
+ return DocumentLexState()->PropGetExpanded(reinterpret_cast<const char *>(wParam),
+ reinterpret_cast<char *>(lParam));
case SCI_GETPROPERTYINT:
- return props.GetInt(reinterpret_cast<const char *>(wParam), lParam);
+ return DocumentLexState()->PropGetInt(reinterpret_cast<const char *>(wParam), lParam);
case SCI_SETKEYWORDS:
- if (wParam < numWordLists) {
- keyWordLists[wParam]->Clear();
- keyWordLists[wParam]->Set(reinterpret_cast<const char *>(lParam));
- }
+ DocumentLexState()->SetWordList(wParam, reinterpret_cast<const char *>(lParam));
break;
case SCI_SETLEXERLANGUAGE:
- SetLexerLanguage(reinterpret_cast<const char *>(lParam));
+ DocumentLexState()->SetLexerLanguage(reinterpret_cast<const char *>(lParam));
break;
case SCI_GETLEXERLANGUAGE:
- return StringResult(lParam, lexCurrent ? lexCurrent->languageName : "");
+ return StringResult(lParam, DocumentLexState()->GetName());
+
+ case SCI_PRIVATELEXERCALL:
+ return reinterpret_cast<sptr_t>(
+ DocumentLexState()->PrivateCall(wParam, reinterpret_cast<void *>(lParam)));
case SCI_GETSTYLEBITSNEEDED:
- return lexCurrent ? lexCurrent->GetStyleBitsNeeded() : 5;
+ return DocumentLexState()->GetStyleBitsNeeded();
+
+ case SCI_PROPERTYNAMES:
+ return StringResult(lParam, DocumentLexState()->PropertyNames());
+
+ case SCI_PROPERTYTYPE:
+ return DocumentLexState()->PropertyType(reinterpret_cast<const char *>(wParam));
+
+ case SCI_DESCRIBEPROPERTY:
+ return StringResult(lParam, DocumentLexState()->DescribeProperty(reinterpret_cast<const char *>(wParam)));
+
+ case SCI_DESCRIBEKEYWORDSETS:
+ return StringResult(lParam, DocumentLexState()->DescribeWordListSets());
#endif
diff --git a/plugins/scintilla/scintilla/ScintillaBase.h b/plugins/scintilla/scintilla/ScintillaBase.h
index f1fdc5d..2035108 100644
--- a/plugins/scintilla/scintilla/ScintillaBase.h
+++ b/plugins/scintilla/scintilla/ScintillaBase.h
@@ -12,6 +12,10 @@
namespace Scintilla {
#endif
+#ifdef SCI_LEXER
+class LexState;
+#endif
+
/**
*/
class ScintillaBase : public Editor {
@@ -44,12 +48,7 @@ protected:
int maxListWidth; /// Maximum width of list, in average character widths
#ifdef SCI_LEXER
- bool performingStyle; ///< Prevent reentrance
- int lexLanguage;
- const LexerModule *lexCurrent;
- PropSetSimple props;
- enum {numWordLists=KEYWORDSET_MAX+1};
- WordList *keyWordLists[numWordLists+1];
+ LexState *DocumentLexState();
void SetLexer(uptr_t wParam);
void SetLexerLanguage(const char *languageName);
void Colourise(int start, int end);
@@ -76,7 +75,7 @@ protected:
void AutoCompleteCharacterDeleted();
void AutoCompleteCompleted();
void AutoCompleteMoveToCurrentWord();
- static void AutoCompleteDoubleClick(void* p);
+ static void AutoCompleteDoubleClick(void *p);
void CallTipClick();
void CallTipShow(Point pt, const char *defn);
@@ -87,7 +86,9 @@ protected:
virtual void ButtonDown(Point pt, unsigned int curTime, bool shift, bool ctrl, bool alt);
- virtual void NotifyStyleToNeeded(int endStyleNeeded);
+ void NotifyStyleToNeeded(int endStyleNeeded);
+ void NotifyLexerChanged(Document *doc, void *userData);
+
public:
// Public so scintilla_send_message can use it
virtual sptr_t WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam);
diff --git a/plugins/scintilla/scintilla/ScintillaGTK.cxx b/plugins/scintilla/scintilla/ScintillaGTK.cxx
index c1243a4..5682fde 100644
--- a/plugins/scintilla/scintilla/ScintillaGTK.cxx
+++ b/plugins/scintilla/scintilla/ScintillaGTK.cxx
@@ -7,6 +7,7 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
+#include <assert.h>
#include <ctype.h>
#include <time.h>
@@ -22,14 +23,11 @@
#include "windows.h"
#endif
+#include "ILexer.h"
#include "Scintilla.h"
#include "ScintillaWidget.h"
#ifdef SCI_LEXER
#include "SciLexer.h"
-#include "PropSet.h"
-#include "PropSetSimple.h"
-#include "Accessor.h"
-#include "KeyWords.h"
#endif
#include "SVector.h"
#include "SplitVector.h"
@@ -54,28 +52,48 @@
#include "ScintillaBase.h"
#include "UniConversion.h"
-#include "gtk/gtksignal.h"
-#include "gtk/gtkmarshal.h"
-#if GLIB_MAJOR_VERSION >= 2
#include "scintilla-marshal.h"
-#endif
#ifdef SCI_LEXER
#include <glib.h>
#include <gmodule.h>
+#include "LexerModule.h"
#include "ExternalLexer.h"
#endif
-#define INTERNATIONAL_INPUT
+#include "Converter.h"
-#if !PLAT_GTK_WIN32 || GTK_MAJOR_VERSION >= 2
-#define USE_CONVERTER
+#if GTK_CHECK_VERSION(2,20,0)
+#define IS_WIDGET_REALIZED(w) (gtk_widget_get_realized(GTK_WIDGET(w)))
+#define IS_WIDGET_MAPPED(w) (gtk_widget_get_mapped(GTK_WIDGET(w)))
+#define IS_WIDGET_VISIBLE(w) (gtk_widget_get_visible(GTK_WIDGET(w)))
+#else
+#define IS_WIDGET_REALIZED(w) (GTK_WIDGET_REALIZED(w))
+#define IS_WIDGET_MAPPED(w) (GTK_WIDGET_MAPPED(w))
+#define IS_WIDGET_VISIBLE(w) (GTK_WIDGET_VISIBLE(w))
#endif
-#ifdef USE_CONVERTER
-#include "Converter.h"
+#if GTK_CHECK_VERSION(2,22,0)
+#define USE_CAIRO 1
#endif
+static GdkWindow *WindowFromWidget(GtkWidget *w) {
+#if GTK_CHECK_VERSION(3,0,0)
+ return gtk_widget_get_window(w);
+#else
+ return w->window;
+#endif
+}
+
+static GdkWindow *PWindow(const Window &w) {
+ GtkWidget *widget = reinterpret_cast<GtkWidget *>(w.GetID());
+#if GTK_CHECK_VERSION(3,0,0)
+ return gtk_widget_get_window(widget);
+#else
+ return widget->window;
+#endif
+}
+
#ifdef _MSC_VER
// Constant conditional expressions are because of GTK+ headers
#pragma warning(disable: 4127)
@@ -87,11 +105,7 @@
#define USE_GTK_CLIPBOARD
#endif
-#if GLIB_MAJOR_VERSION < 2
-#define OBJECT_CLASS GtkObjectClass
-#else
#define OBJECT_CLASS GObjectClass
-#endif
#ifdef SCI_NAMESPACE
using namespace Scintilla;
@@ -104,8 +118,8 @@ class ScintillaGTK : public ScintillaBase {
Window wText;
Window scrollbarv;
Window scrollbarh;
- GtkObject *adjustmentv;
- GtkObject *adjustmenth;
+ GtkAdjustment *adjustmentv;
+ GtkAdjustment *adjustmenth;
int scrollBarWidth;
int scrollBarHeight;
@@ -135,17 +149,9 @@ class ScintillaGTK : public ScintillaBase {
CLIPFORMAT cfColumnSelect;
#endif
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
- // Input context used for supporting internationalized key entry
- GdkIC *ic;
- GdkICAttr *ic_attr;
-#else
Window wPreedit;
Window wPreeditDraw;
GtkIMContext *im_context;
-#endif
-#endif
// Wheel mouse support
unsigned int linesPerScroll;
@@ -153,7 +159,11 @@ class ScintillaGTK : public ScintillaBase {
gint lastWheelMouseDirection;
gint wheelMouseIntensity;
+#if GTK_CHECK_VERSION(3,0,0)
+ cairo_rectangle_list_t *rgnUpdate;
+#else
GdkRegion *rgnUpdate;
+#endif
// Private so ScintillaGTK objects can not be copied
ScintillaGTK(const ScintillaGTK &);
@@ -195,6 +205,8 @@ private:
void NotifyKey(int key, int modifiers);
void NotifyURIDropped(const char *list);
const char *CharacterSetID() const;
+ virtual CaseFolder *CaseFolderForEncoding();
+ virtual std::string CaseMapString(const std::string &s, int caseMapping);
virtual int KeyDefault(int key, int modifiers);
virtual void CopyToClipboard(const SelectionText &selectedText);
virtual void Copy();
@@ -225,15 +237,25 @@ private:
static void Map(GtkWidget *widget);
void UnMapThis();
static void UnMap(GtkWidget *widget);
- static gint CursorMoved(GtkWidget *widget, int xoffset, int yoffset, ScintillaGTK *sciThis);
gint FocusInThis(GtkWidget *widget);
static gint FocusIn(GtkWidget *widget, GdkEventFocus *event);
gint FocusOutThis(GtkWidget *widget);
static gint FocusOut(GtkWidget *widget, GdkEventFocus *event);
static void SizeRequest(GtkWidget *widget, GtkRequisition *requisition);
+ static void GetPreferredWidth(GtkWidget *widget, gint *minimalWidth, gint *naturalWidth);
+ static void GetPreferredHeight(GtkWidget *widget, gint *minimalHeight, gint *naturalHeight);
static void SizeAllocate(GtkWidget *widget, GtkAllocation *allocation);
- gint Expose(GtkWidget *widget, GdkEventExpose *ose);
- static gint ExposeMain(GtkWidget *widget, GdkEventExpose *ose);
+#if GTK_CHECK_VERSION(3,0,0)
+ gboolean DrawTextThis(cairo_t *cr);
+ static gboolean DrawText(GtkWidget *widget, cairo_t *cr, ScintillaGTK *sciThis);
+ gboolean DrawThis(cairo_t *cr);
+ static gboolean DrawMain(GtkWidget *widget, cairo_t *cr);
+#else
+ gboolean ExposeTextThis(GtkWidget *widget, GdkEventExpose *ose);
+ static gboolean ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
+ gboolean Expose(GtkWidget *widget, GdkEventExpose *ose);
+ static gboolean ExposeMain(GtkWidget *widget, GdkEventExpose *ose);
+#endif
static void Draw(GtkWidget *widget, GdkRectangle *area);
void ForAll(GtkCallback callback, gpointer callback_data);
static void MainForAll(GtkContainer *container, gboolean include_internals, GtkCallback callback, gpointer callback_data);
@@ -243,36 +265,25 @@ private:
gint PressThis(GdkEventButton *event);
static gint Press(GtkWidget *widget, GdkEventButton *event);
static gint MouseRelease(GtkWidget *widget, GdkEventButton *event);
-#if PLAT_GTK_WIN32 || (GTK_MAJOR_VERSION >= 2)
static gint ScrollEvent(GtkWidget *widget, GdkEventScroll *event);
-#endif
static gint Motion(GtkWidget *widget, GdkEventMotion *event);
gboolean KeyThis(GdkEventKey *event);
static gboolean KeyPress(GtkWidget *widget, GdkEventKey *event);
static gboolean KeyRelease(GtkWidget *widget, GdkEventKey *event);
-#if GTK_MAJOR_VERSION >= 2
gboolean ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose);
static gboolean ExposePreedit(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
void CommitThis(char *str);
static void Commit(GtkIMContext *context, char *str, ScintillaGTK *sciThis);
void PreeditChangedThis();
static void PreeditChanged(GtkIMContext *context, ScintillaGTK *sciThis);
-#endif
- static gint StyleSetText(GtkWidget *widget, GtkStyle *previous, void*);
- static gint RealizeText(GtkWidget *widget, void*);
-#if GLIB_MAJOR_VERSION < 2
- static void Destroy(GtkObject *object);
-#else
+ static void StyleSetText(GtkWidget *widget, GtkStyle *previous, void*);
+ static void RealizeText(GtkWidget *widget, void*);
static void Destroy(GObject *object);
-#endif
static void SelectionReceived(GtkWidget *widget, GtkSelectionData *selection_data,
guint time);
static void SelectionGet(GtkWidget *widget, GtkSelectionData *selection_data,
guint info, guint time);
static gint SelectionClear(GtkWidget *widget, GdkEventSelection *selection_event);
-#if GTK_MAJOR_VERSION < 2
- static gint SelectionNotify(GtkWidget *widget, GdkEventSelection *selection_event);
-#endif
static void DragBegin(GtkWidget *widget, GdkDragContext *context);
gboolean DragMotionThis(GdkDragContext *context, gint x, gint y, guint dragtime);
static gboolean DragMotion(GtkWidget *widget, GdkDragContext *context,
@@ -286,15 +297,18 @@ private:
gint x, gint y, GtkSelectionData *selection_data, guint info, guint time);
static void DragDataGet(GtkWidget *widget, GdkDragContext *context,
GtkSelectionData *selection_data, guint info, guint time);
- static gint TimeOut(ScintillaGTK *sciThis);
- static gint IdleCallback(ScintillaGTK *sciThis);
- static void PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *widget);
-
- gint ExposeTextThis(GtkWidget *widget, GdkEventExpose *ose);
- static gint ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis);
-
- static gint ExposeCT(GtkWidget *widget, GdkEventExpose *ose, CallTip *ct);
- static gint PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis);
+ static gboolean TimeOut(ScintillaGTK *sciThis);
+ static gboolean IdleCallback(ScintillaGTK *sciThis);
+ static gboolean StyleIdle(ScintillaGTK *sciThis);
+ virtual void QueueStyling(int upTo);
+ static void PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis);
+
+#if GTK_CHECK_VERSION(3,0,0)
+ static gboolean DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip);
+#else
+ static gboolean ExposeCT(GtkWidget *widget, GdkEventExpose *ose, CallTip *ct);
+#endif
+ static gboolean PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis);
static sptr_t DirectFunction(ScintillaGTK *sciThis,
unsigned int iMessage, uptr_t wParam, sptr_t lParam);
@@ -307,9 +321,6 @@ enum {
};
static gint scintilla_signals[LAST_SIGNAL] = { 0 };
-#if GLIB_MAJOR_VERSION < 2
-static GtkWidgetClass *parent_class = NULL;
-#endif
enum {
TARGET_STRING,
@@ -352,14 +363,7 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
scrollBarWidth(30), scrollBarHeight(30),
capturedMouse(false), dragWasDropped(false),
lastKey(0), rectangularSelectionModifier(SCMOD_CTRL), parentClass(0),
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
- ic(NULL),
- ic_attr(NULL),
-#else
im_context(NULL),
-#endif
-#endif
lastWheelMouseDirection(0),
wheelMouseIntensity(0),
rgnUpdate(0) {
@@ -394,94 +398,62 @@ ScintillaGTK::ScintillaGTK(_ScintillaObject *sci_) :
}
ScintillaGTK::~ScintillaGTK() {
+ g_idle_remove_by_data(this);
}
void ScintillaGTK::RealizeThis(GtkWidget *widget) {
//Platform::DebugPrintf("ScintillaGTK::realize this\n");
+#if GTK_CHECK_VERSION(2,20,0)
+ gtk_widget_set_realized(widget, TRUE);
+#else
GTK_WIDGET_SET_FLAGS(widget, GTK_REALIZED);
+#endif
GdkWindowAttr attrs;
attrs.window_type = GDK_WINDOW_CHILD;
- attrs.x = widget->allocation.x;
- attrs.y = widget->allocation.y;
- attrs.width = widget->allocation.width;
- attrs.height = widget->allocation.height;
+ GtkAllocation allocation;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_get_allocation(widget, &allocation);
+#else
+ allocation = widget->allocation;
+#endif
+ attrs.x = allocation.x;
+ attrs.y = allocation.y;
+ attrs.width = allocation.width;
+ attrs.height = allocation.height;
attrs.wclass = GDK_INPUT_OUTPUT;
attrs.visual = gtk_widget_get_visual(widget);
+#if !GTK_CHECK_VERSION(3,0,0)
attrs.colormap = gtk_widget_get_colormap(widget);
+#endif
attrs.event_mask = gtk_widget_get_events(widget) | GDK_EXPOSURE_MASK;
GdkCursor *cursor = gdk_cursor_new(GDK_XTERM);
attrs.cursor = cursor;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_set_window(widget, gdk_window_new(gtk_widget_get_parent_window(widget), &attrs,
+ GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_CURSOR));
+ gdk_window_set_user_data(gtk_widget_get_window(widget), widget);
+ gdk_window_set_background(gtk_widget_get_window(widget),
+ &(gtk_widget_get_style(widget)->bg[GTK_STATE_NORMAL]));
+ gdk_window_show(gtk_widget_get_window(widget));
+ gdk_cursor_unref(cursor);
+ // Deprecated: should chain up to parent class' "realize" implementation
+ gtk_widget_style_attach(widget);
+#else
widget->window = gdk_window_new(gtk_widget_get_parent_window(widget), &attrs,
GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP | GDK_WA_CURSOR);
gdk_window_set_user_data(widget->window, widget);
gdk_window_set_background(widget->window, &widget->style->bg[GTK_STATE_NORMAL]);
gdk_window_show(widget->window);
- gdk_cursor_destroy(cursor);
+ gdk_cursor_unref(cursor);
widget->style = gtk_style_attach(widget->style, widget->window);
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
- if (gdk_im_ready() && (ic_attr = gdk_ic_attr_new()) != NULL) {
- gint width, height;
- GdkColormap *colormap;
- GdkEventMask mask;
- GdkICAttr *attr = ic_attr;
- GdkICAttributesType attrmask = GDK_IC_ALL_REQ;
- GdkIMStyle style;
- GdkIMStyle supported_style = (GdkIMStyle) (GDK_IM_PREEDIT_NONE |
- GDK_IM_PREEDIT_NOTHING |
- GDK_IM_PREEDIT_POSITION |
- GDK_IM_STATUS_NONE |
- GDK_IM_STATUS_NOTHING);
-
- if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
- supported_style = (GdkIMStyle) ((int) supported_style & ~GDK_IM_PREEDIT_POSITION);
-
- attr->style = style = gdk_im_decide_style(supported_style);
- attr->client_window = widget->window;
-
- if ((colormap = gtk_widget_get_colormap (widget)) != gtk_widget_get_default_colormap ()) {
- attrmask = (GdkICAttributesType) ((int) attrmask | GDK_IC_PREEDIT_COLORMAP);
- attr->preedit_colormap = colormap;
- }
-
- switch (style & GDK_IM_PREEDIT_MASK) {
- case GDK_IM_PREEDIT_POSITION:
- if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) {
- g_warning("over-the-spot style requires fontset");
- break;
- }
-
- attrmask = (GdkICAttributesType) ((int) attrmask | GDK_IC_PREEDIT_POSITION_REQ);
- gdk_window_get_size(widget->window, &width, &height);
- attr->spot_location.x = 0;
- attr->spot_location.y = height;
- attr->preedit_area.x = 0;
- attr->preedit_area.y = 0;
- attr->preedit_area.width = width;
- attr->preedit_area.height = height;
- attr->preedit_fontset = widget->style->font;
-
- break;
- }
- ic = gdk_ic_new(attr, attrmask);
-
- if (ic == NULL) {
- g_warning("Can't create input context.");
- } else {
- mask = gdk_window_get_events(widget->window);
- mask = (GdkEventMask) ((int) mask | gdk_ic_get_events(ic));
- gdk_window_set_events(widget->window, mask);
-
- if (GTK_WIDGET_HAS_FOCUS(widget))
- gdk_im_begin(ic, widget->window);
- }
- }
-#else
+#endif
wPreedit = gtk_window_new(GTK_WINDOW_POPUP);
wPreeditDraw = gtk_drawing_area_new();
GtkWidget *predrw = PWidget(wPreeditDraw); // No code inside the G_OBJECT macro
+#if !GTK_CHECK_VERSION(3,0,0)
g_signal_connect(G_OBJECT(predrw), "expose_event",
G_CALLBACK(ExposePreedit), this);
+#endif
gtk_container_add(GTK_CONTAINER(PWidget(wPreedit)), predrw);
gtk_widget_realize(PWidget(wPreedit));
gtk_widget_realize(predrw);
@@ -492,24 +464,34 @@ void ScintillaGTK::RealizeThis(GtkWidget *widget) {
G_CALLBACK(Commit), this);
g_signal_connect(G_OBJECT(im_context), "preedit_changed",
G_CALLBACK(PreeditChanged), this);
- gtk_im_context_set_client_window(im_context, widget->window);
-#endif
-#endif
+ gtk_im_context_set_client_window(im_context, WindowFromWidget(widget));
GtkWidget *widtxt = PWidget(wText); // // No code inside the G_OBJECT macro
-#if GLIB_MAJOR_VERSION < 2
- gtk_signal_connect_after(GTK_OBJECT(widtxt), "style_set",
- GtkSignalFunc(ScintillaGTK::StyleSetText), NULL);
- gtk_signal_connect_after(GTK_OBJECT(widtxt), "realize",
- GtkSignalFunc(ScintillaGTK::RealizeText), NULL);
-#else
g_signal_connect_after(G_OBJECT(widtxt), "style_set",
G_CALLBACK(ScintillaGTK::StyleSetText), NULL);
g_signal_connect_after(G_OBJECT(widtxt), "realize",
G_CALLBACK(ScintillaGTK::RealizeText), NULL);
-#endif
gtk_widget_realize(widtxt);
gtk_widget_realize(PWidget(scrollbarv));
gtk_widget_realize(PWidget(scrollbarh));
+
+ cursor = gdk_cursor_new(GDK_XTERM);
+ gdk_window_set_cursor(PWindow(wText), cursor);
+ gdk_cursor_unref(cursor);
+
+ cursor = gdk_cursor_new(GDK_LEFT_PTR);
+ gdk_window_set_cursor(PWindow(scrollbarv), cursor);
+ gdk_cursor_unref(cursor);
+
+ cursor = gdk_cursor_new(GDK_LEFT_PTR);
+ gdk_window_set_cursor(PWindow(scrollbarh), cursor);
+ gdk_cursor_unref(cursor);
+
+ gtk_selection_add_targets(widget, GDK_SELECTION_PRIMARY,
+ clipboardCopyTargets, nClipboardCopyTargets);
+#ifndef USE_GTK_CLIPBOARD
+ gtk_selection_add_targets(widget, atomClipboard,
+ clipboardPasteTargets, nClipboardPasteTargets);
+#endif
}
void ScintillaGTK::Realize(GtkWidget *widget) {
@@ -519,30 +501,26 @@ void ScintillaGTK::Realize(GtkWidget *widget) {
void ScintillaGTK::UnRealizeThis(GtkWidget *widget) {
try {
- if (GTK_WIDGET_MAPPED(widget)) {
+ gtk_selection_clear_targets(widget, GDK_SELECTION_PRIMARY);
+#ifndef USE_GTK_CLIPBOARD
+ gtk_selection_clear_targets(widget, atomClipboard);
+#endif
+
+ if (IS_WIDGET_MAPPED(widget)) {
gtk_widget_unmap(widget);
}
+#if GTK_CHECK_VERSION(2,20,0)
+ gtk_widget_set_realized(widget, FALSE);
+#else
GTK_WIDGET_UNSET_FLAGS(widget, GTK_REALIZED);
+#endif
gtk_widget_unrealize(PWidget(wText));
gtk_widget_unrealize(PWidget(scrollbarv));
gtk_widget_unrealize(PWidget(scrollbarh));
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
- if (ic) {
- gdk_ic_destroy(ic);
- ic = NULL;
- }
- if (ic_attr) {
- gdk_ic_attr_destroy(ic_attr);
- ic_attr = NULL;
- }
-#else
gtk_widget_unrealize(PWidget(wPreedit));
gtk_widget_unrealize(PWidget(wPreeditDraw));
g_object_unref(im_context);
im_context = NULL;
-#endif
-#endif
if (GTK_WIDGET_CLASS(parentClass)->unrealize)
GTK_WIDGET_CLASS(parentClass)->unrealize(widget);
@@ -559,8 +537,8 @@ void ScintillaGTK::UnRealize(GtkWidget *widget) {
static void MapWidget(GtkWidget *widget) {
if (widget &&
- GTK_WIDGET_VISIBLE(widget) &&
- !GTK_WIDGET_MAPPED(widget)) {
+ IS_WIDGET_VISIBLE(widget) &&
+ !IS_WIDGET_MAPPED(widget)) {
gtk_widget_map(widget);
}
}
@@ -568,7 +546,11 @@ static void MapWidget(GtkWidget *widget) {
void ScintillaGTK::MapThis() {
try {
//Platform::DebugPrintf("ScintillaGTK::map this\n");
+#if GTK_CHECK_VERSION(2,20,0)
+ gtk_widget_set_mapped(PWidget(wMain), TRUE);
+#else
GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_MAPPED);
+#endif
MapWidget(PWidget(wText));
MapWidget(PWidget(scrollbarh));
MapWidget(PWidget(scrollbarv));
@@ -576,7 +558,7 @@ void ScintillaGTK::MapThis() {
scrollbarv.SetCursor(Window::cursorArrow);
scrollbarh.SetCursor(Window::cursorArrow);
ChangeSize();
- gdk_window_show(PWidget(wMain)->window);
+ gdk_window_show(PWindow(wMain));
} catch (...) {
errorStatus = SC_STATUS_FAILURE;
}
@@ -590,9 +572,13 @@ void ScintillaGTK::Map(GtkWidget *widget) {
void ScintillaGTK::UnMapThis() {
try {
//Platform::DebugPrintf("ScintillaGTK::unmap this\n");
+#if GTK_CHECK_VERSION(2,20,0)
+ gtk_widget_set_mapped(PWidget(wMain), FALSE);
+#else
GTK_WIDGET_UNSET_FLAGS(PWidget(wMain), GTK_MAPPED);
+#endif
DropGraphics();
- gdk_window_hide(PWidget(wMain)->window);
+ gdk_window_hide(PWindow(wMain));
gtk_widget_unmap(PWidget(wText));
gtk_widget_unmap(PWidget(scrollbarh));
gtk_widget_unmap(PWidget(scrollbarv));
@@ -624,43 +610,9 @@ void ScintillaGTK::MainForAll(GtkContainer *container, gboolean include_internal
}
}
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
-gint ScintillaGTK::CursorMoved(GtkWidget *widget, int xoffset, int yoffset, ScintillaGTK *sciThis) {
- if (GTK_WIDGET_HAS_FOCUS(widget) && gdk_im_ready() && sciThis->ic &&
- (gdk_ic_get_style(sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
- sciThis->ic_attr->spot_location.x = xoffset;
- sciThis->ic_attr->spot_location.y = yoffset;
- gdk_ic_set_attr(sciThis->ic, sciThis->ic_attr, GDK_IC_SPOT_LOCATION);
- }
- return FALSE;
-}
-#else
-gint ScintillaGTK::CursorMoved(GtkWidget *, int xoffset, int yoffset, ScintillaGTK *sciThis) {
- GdkRectangle area;
- area.x = xoffset;
- area.y = yoffset;
- area.width = 1;
- area.height = 1;
- gtk_im_context_set_cursor_location(sciThis->im_context, &area);
- return FALSE;
-}
-#endif
-#else
-gint ScintillaGTK::CursorMoved(GtkWidget *, int, int, ScintillaGTK *) {
- return FALSE;
-}
-#endif
-
gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
try {
- GTK_WIDGET_SET_FLAGS(widget, GTK_HAS_FOCUS);
SetFocusState(true);
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
- if (ic)
- gdk_im_begin(ic, widget->window);
-#else
if (im_context != NULL) {
gchar *str = NULL;
gint cursor_pos;
@@ -676,8 +628,6 @@ gint ScintillaGTK::FocusInThis(GtkWidget *widget) {
g_free(str);
gtk_im_context_focus_in(im_context);
}
-#endif
-#endif
} catch (...) {
errorStatus = SC_STATUS_FAILURE;
@@ -692,19 +642,12 @@ gint ScintillaGTK::FocusIn(GtkWidget *widget, GdkEventFocus * /*event*/) {
gint ScintillaGTK::FocusOutThis(GtkWidget *widget) {
try {
- GTK_WIDGET_UNSET_FLAGS(widget, GTK_HAS_FOCUS);
SetFocusState(false);
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
- gdk_im_end();
-#else
if (PWidget(wPreedit) != NULL)
gtk_widget_hide(PWidget(wPreedit));
if (im_context != NULL)
gtk_im_context_focus_out(im_context);
-#endif
-#endif
} catch (...) {
errorStatus = SC_STATUS_FAILURE;
@@ -719,39 +662,47 @@ gint ScintillaGTK::FocusOut(GtkWidget *widget, GdkEventFocus * /*event*/) {
void ScintillaGTK::SizeRequest(GtkWidget *widget, GtkRequisition *requisition) {
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
- requisition->width = 600;
- requisition->height = gdk_screen_height();
+ requisition->width = 1;
+ requisition->height = 1;
GtkRequisition child_requisition;
+#if GTK_CHECK_VERSION(3,0,0)
+ gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarh), NULL, &child_requisition);
+ gtk_widget_get_preferred_size(PWidget(sciThis->scrollbarv), NULL, &child_requisition);
+#else
gtk_widget_size_request(PWidget(sciThis->scrollbarh), &child_requisition);
gtk_widget_size_request(PWidget(sciThis->scrollbarv), &child_requisition);
+#endif
+}
+
+void ScintillaGTK::GetPreferredWidth(GtkWidget *widget, gint *minimalWidth, gint *naturalWidth) {
+ GtkRequisition requisition;
+ SizeRequest(widget, &requisition);
+ *minimalWidth = *naturalWidth = requisition.width;
+}
+
+void ScintillaGTK::GetPreferredHeight(GtkWidget *widget, gint *minimalHeight, gint *naturalHeight) {
+ GtkRequisition requisition;
+ SizeRequest(widget, &requisition);
+ *minimalHeight = *naturalHeight = requisition.height;
}
void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) {
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
try {
+#if GTK_CHECK_VERSION(2,20,0)
+ gtk_widget_set_allocation(widget, allocation);
+#else
widget->allocation = *allocation;
- if (GTK_WIDGET_REALIZED(widget))
- gdk_window_move_resize(widget->window,
- widget->allocation.x,
- widget->allocation.y,
- widget->allocation.width,
- widget->allocation.height);
+#endif
+ if (IS_WIDGET_REALIZED(widget))
+ gdk_window_move_resize(WindowFromWidget(widget),
+ allocation->x,
+ allocation->y,
+ allocation->width,
+ allocation->height);
sciThis->Resize(allocation->width, allocation->height);
-#ifdef INTERNATIONAL_INPUT
-#if GTK_MAJOR_VERSION < 2
- if (sciThis->ic && (gdk_ic_get_style(sciThis->ic) & GDK_IM_PREEDIT_POSITION)) {
- gint width, height;
-
- gdk_window_get_size(widget->window, &width, &height);
- sciThis->ic_attr->preedit_area.width = width;
- sciThis->ic_attr->preedit_area.height = height;
-
- gdk_ic_set_attr(sciThis->ic, sciThis->ic_attr, GDK_IC_PREEDIT_AREA);
- }
-#endif
-#endif
} catch (...) {
sciThis->errorStatus = SC_STATUS_FAILURE;
}
@@ -760,10 +711,15 @@ void ScintillaGTK::SizeAllocate(GtkWidget *widget, GtkAllocation *allocation) {
void ScintillaGTK::Initialise() {
//Platform::DebugPrintf("ScintillaGTK::Initialise\n");
parentClass = reinterpret_cast<GtkWidgetClass *>(
- gtk_type_class(gtk_container_get_type()));
+ g_type_class_ref(gtk_container_get_type()));
+#if GTK_CHECK_VERSION(2,20,0)
+ gtk_widget_set_can_focus(PWidget(wMain), TRUE);
+ gtk_widget_set_sensitive(PWidget(wMain), TRUE);
+#else
GTK_WIDGET_SET_FLAGS(PWidget(wMain), GTK_CAN_FOCUS);
GTK_WIDGET_SET_FLAGS(GTK_WIDGET(PWidget(wMain)), GTK_SENSITIVE);
+#endif
gtk_widget_set_events(PWidget(wMain),
GDK_EXPOSURE_MASK
| GDK_STRUCTURE_MASK
@@ -780,61 +736,47 @@ void ScintillaGTK::Initialise() {
gtk_widget_set_parent(PWidget(wText), PWidget(wMain));
GtkWidget *widtxt = PWidget(wText); // No code inside the G_OBJECT macro
gtk_widget_show(widtxt);
-#if GLIB_MAJOR_VERSION < 2
- gtk_signal_connect(GTK_OBJECT(widtxt), "expose_event",
- GtkSignalFunc(ScintillaGTK::ExposeText), this);
+#if GTK_CHECK_VERSION(3,0,0)
+ g_signal_connect(G_OBJECT(widtxt), "draw",
+ G_CALLBACK(ScintillaGTK::DrawText), this);
#else
g_signal_connect(G_OBJECT(widtxt), "expose_event",
G_CALLBACK(ScintillaGTK::ExposeText), this);
#endif
gtk_widget_set_events(widtxt, GDK_EXPOSURE_MASK);
-#if GTK_MAJOR_VERSION >= 2
// Avoid background drawing flash
gtk_widget_set_double_buffered(widtxt, FALSE);
-#endif
- gtk_drawing_area_size(GTK_DRAWING_AREA(widtxt),
- 100,100);
- adjustmentv = gtk_adjustment_new(0.0, 0.0, 201.0, 1.0, 20.0, 20.0);
+ gtk_widget_set_size_request(widtxt, 100, 100);
+ adjustmentv = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 201.0, 1.0, 20.0, 20.0));
scrollbarv = gtk_vscrollbar_new(GTK_ADJUSTMENT(adjustmentv));
- GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarv), GTK_CAN_FOCUS);
-#if GLIB_MAJOR_VERSION < 2
- gtk_signal_connect(adjustmentv, "value_changed",
- GtkSignalFunc(ScrollSignal), this);
+#if GTK_CHECK_VERSION(2,20,0)
+ gtk_widget_set_can_focus(PWidget(scrollbarv), FALSE);
#else
+ GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarv), GTK_CAN_FOCUS);
+#endif
g_signal_connect(G_OBJECT(adjustmentv), "value_changed",
G_CALLBACK(ScrollSignal), this);
-#endif
gtk_widget_set_parent(PWidget(scrollbarv), PWidget(wMain));
gtk_widget_show(PWidget(scrollbarv));
- adjustmenth = gtk_adjustment_new(0.0, 0.0, 101.0, 1.0, 20.0, 20.0);
+ adjustmenth = GTK_ADJUSTMENT(gtk_adjustment_new(0.0, 0.0, 101.0, 1.0, 20.0, 20.0));
scrollbarh = gtk_hscrollbar_new(GTK_ADJUSTMENT(adjustmenth));
- GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarh), GTK_CAN_FOCUS);
-#if GLIB_MAJOR_VERSION < 2
- gtk_signal_connect(adjustmenth, "value_changed",
- GtkSignalFunc(ScrollHSignal), this);
+#if GTK_CHECK_VERSION(2,20,0)
+ gtk_widget_set_can_focus(PWidget(scrollbarh), FALSE);
#else
+ GTK_WIDGET_UNSET_FLAGS(PWidget(scrollbarh), GTK_CAN_FOCUS);
+#endif
g_signal_connect(G_OBJECT(adjustmenth), "value_changed",
G_CALLBACK(ScrollHSignal), this);
-#endif
gtk_widget_set_parent(PWidget(scrollbarh), PWidget(wMain));
gtk_widget_show(PWidget(scrollbarh));
gtk_widget_grab_focus(PWidget(wMain));
- gtk_selection_add_targets(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY,
- clipboardCopyTargets, nClipboardCopyTargets);
-
-#ifndef USE_GTK_CLIPBOARD
- gtk_selection_add_targets(GTK_WIDGET(PWidget(wMain)), atomClipboard,
- clipboardPasteTargets, nClipboardPasteTargets);
-#endif
-
gtk_drag_dest_set(GTK_WIDGET(PWidget(wMain)),
GTK_DEST_DEFAULT_ALL, clipboardPasteTargets, nClipboardPasteTargets,
static_cast<GdkDragAction>(GDK_ACTION_COPY | GDK_ACTION_MOVE));
-#if GLIB_MAJOR_VERSION >= 2
// Set caret period based on GTK settings
gboolean blinkOn = false;
if (g_object_class_find_property(G_OBJECT_GET_CLASS(
@@ -852,7 +794,6 @@ void ScintillaGTK::Initialise() {
} else {
caret.period = 0;
}
-#endif
SetTicking(true);
}
@@ -870,12 +811,8 @@ void ScintillaGTK::DisplayCursor(Window::Cursor c) {
}
bool ScintillaGTK::DragThreshold(Point ptStart, Point ptNow) {
-#if GTK_MAJOR_VERSION < 2
- return Editor::DragThreshold(ptStart, ptNow);
-#else
return gtk_drag_check_threshold(GTK_WIDGET(PWidget(wMain)),
ptStart.x, ptStart.y, ptNow.x, ptNow.y);
-#endif
}
void ScintillaGTK::StartDrag() {
@@ -889,9 +826,9 @@ void ScintillaGTK::StartDrag() {
reinterpret_cast<GdkEvent *>(&evbtn));
}
-#ifdef USE_CONVERTER
static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSetDest,
- const char *charSetSource, bool transliterations) {
+ const char *charSetSource, bool transliterations, bool silent=false) {
+ // s is not const because of different versions of iconv disagreeing about const
*lenResult = 0;
char *destForm = 0;
Converter conv(charSetDest, charSetSource, transliterations);
@@ -903,7 +840,9 @@ static char *ConvertText(int *lenResult, char *s, size_t len, const char *charSe
size_t outLeft = len*3+1;
size_t conversions = conv.Convert(&pin, &inLeft, &pout, &outLeft);
if (conversions == ((size_t)(-1))) {
-fprintf(stderr, "iconv %s->%s failed for %s\n", charSetSource, charSetDest, static_cast<char *>(s));
+ if (!silent)
+ fprintf(stderr, "iconv %s->%s failed for %s\n",
+ charSetSource, charSetDest, static_cast<char *>(s));
delete []destForm;
destForm = 0;
} else {
@@ -921,7 +860,6 @@ fprintf(stderr, "Can not iconv %s %s\n", charSetDest, charSetSource);
}
return destForm;
}
-#endif
// Returns the target converted to UTF8.
// Return the length in bytes.
@@ -933,7 +871,6 @@ int ScintillaGTK::TargetAsUTF8(char *text) {
}
} else {
// Need to convert
-#ifdef USE_CONVERTER
const char *charSetBuffer = CharacterSetID();
if (*charSetBuffer) {
//~ fprintf(stderr, "AsUTF8 %s %d %0d-%0d\n", charSetBuffer, targetLength, targetStart, targetEnd);
@@ -954,10 +891,6 @@ int ScintillaGTK::TargetAsUTF8(char *text) {
pdoc->GetCharRange(text, targetStart, targetLength);
}
}
-#else
- // Fail
- return 0;
-#endif
}
//~ fprintf(stderr, "Length = %d bytes\n", targetLength);
return targetLength;
@@ -974,14 +907,11 @@ int ScintillaGTK::EncodedFromUTF8(char *utf8, char *encoded) {
return inputLength;
} else {
// Need to convert
-#ifdef USE_CONVERTER
const char *charSetBuffer = CharacterSetID();
if (*charSetBuffer) {
-//~ fprintf(stderr, "Encode %s %d\n", charSetBuffer, inputLength);
int outLength = 0;
char *tmpEncoded = ConvertText(&outLength, utf8, inputLength, charSetBuffer, "UTF-8", true);
if (tmpEncoded) {
-//~ fprintf(stderr, " \"%s\"\n", tmpEncoded);
if (encoded) {
memcpy(encoded, tmpEncoded, outLength);
}
@@ -994,19 +924,19 @@ int ScintillaGTK::EncodedFromUTF8(char *utf8, char *encoded) {
}
return inputLength;
}
-#endif
}
// Fail
return 0;
}
bool ScintillaGTK::ValidCodePage(int codePage) const {
- return codePage == 0
- || codePage == SC_CP_UTF8
+ return codePage == 0
+ || codePage == SC_CP_UTF8
|| codePage == 932
|| codePage == 936
+ || codePage == 949
|| codePage == 950
- || codePage == SC_CP_DBCS;
+ || codePage == 1361;
}
sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
@@ -1025,7 +955,7 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
#ifdef SCI_LEXER
case SCI_LOADLEXERLIBRARY:
- LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(wParam));
+ LexerManager::GetInstance()->Load(reinterpret_cast<const char*>(lParam));
break;
#endif
case SCI_TARGETASUTF8:
@@ -1038,10 +968,10 @@ sptr_t ScintillaGTK::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam
case SCI_SETRECTANGULARSELECTIONMODIFIER:
rectangularSelectionModifier = wParam;
break;
-
+
case SCI_GETRECTANGULARSELECTIONMODIFIER:
return rectangularSelectionModifier;
-
+
default:
return ScintillaBase::WndProc(iMessage, wParam, lParam);
}
@@ -1061,9 +991,10 @@ void ScintillaGTK::SetTicking(bool on) {
if (timer.ticking != on) {
timer.ticking = on;
if (timer.ticking) {
- timer.tickerID = reinterpret_cast<TickerID>(g_timeout_add(timer.tickSize, (GSourceFunc)TimeOut, this));
+ timer.tickerID = reinterpret_cast<TickerID>(g_timeout_add(timer.tickSize,
+ reinterpret_cast<GSourceFunc>(TimeOut), this));
} else {
- gtk_timeout_remove(GPOINTER_TO_UINT(timer.tickerID));
+ g_source_remove(GPOINTER_TO_UINT(timer.tickerID));
}
}
timer.ticksToWait = caret.period;
@@ -1072,16 +1003,17 @@ void ScintillaGTK::SetTicking(bool on) {
bool ScintillaGTK::SetIdle(bool on) {
if (on) {
// Start idler, if it's not running.
- if (idler.state == false) {
+ if (!idler.state) {
idler.state = true;
- idler.idlerID = reinterpret_cast<IdlerID>
- (gtk_idle_add((GtkFunction)IdleCallback, this));
+ idler.idlerID = reinterpret_cast<IdlerID>(
+ g_idle_add_full(G_PRIORITY_DEFAULT_IDLE,
+ reinterpret_cast<GSourceFunc>(IdleCallback), this, NULL));
}
} else {
// Stop idler, if it's running
- if (idler.state == true) {
+ if (idler.state) {
idler.state = false;
- gtk_idle_remove(GPOINTER_TO_UINT(idler.idlerID));
+ g_source_remove(GPOINTER_TO_UINT(idler.idlerID));
}
}
return true;
@@ -1102,17 +1034,46 @@ bool ScintillaGTK::HaveMouseCapture() {
return capturedMouse;
}
+#if GTK_CHECK_VERSION(3,0,0)
+
+// Is crcTest completely in crcContainer?
+static bool CRectContains(const cairo_rectangle_t &crcContainer, const cairo_rectangle_t &crcTest) {
+ return
+ (crcTest.x >= crcContainer.x) && ((crcTest.x + crcTest.width) <= (crcContainer.x + crcContainer.width)) &&
+ (crcTest.y >= crcContainer.y) && ((crcTest.y + crcTest.height) <= (crcContainer.y + crcContainer.height));
+}
+
+// Is crcTest completely in crcListContainer?
+// May incorrectly return false if complex shape
+static bool CRectListContains(const cairo_rectangle_list_t *crcListContainer, const cairo_rectangle_t &crcTest) {
+ for (int r=0; r<crcListContainer->num_rectangles; r++) {
+ if (CRectContains(crcListContainer->rectangles[r], crcTest))
+ return true;
+ }
+ return false;
+}
+
+#endif
+
bool ScintillaGTK::PaintContains(PRectangle rc) {
+ // This allows optimization when a rectangle is completely in the update region.
+ // It is OK to return false when too difficult to determine as that just performs extra drawing
bool contains = true;
if (paintState == painting) {
if (!rcPaint.Contains(rc)) {
contains = false;
} else if (rgnUpdate) {
+#if GTK_CHECK_VERSION(3,0,0)
+ cairo_rectangle_t grc = {rc.left, rc.top,
+ rc.right - rc.left, rc.bottom - rc.top};
+ contains = CRectListContains(rgnUpdate, grc);
+#else
GdkRectangle grc = {rc.left, rc.top,
rc.right - rc.left, rc.bottom - rc.top};
if (gdk_region_rect_in(rgnUpdate, &grc) != GDK_OVERLAP_RECTANGLE_IN) {
contains = false;
}
+#endif
}
}
return contains;
@@ -1120,25 +1081,7 @@ bool ScintillaGTK::PaintContains(PRectangle rc) {
// Redraw all of text area. This paint will not be abandoned.
void ScintillaGTK::FullPaint() {
-#if GTK_MAJOR_VERSION < 2
- paintState = painting;
- rcPaint = GetClientRectangle();
- //Platform::DebugPrintf("ScintillaGTK::FullPaint %0d,%0d %0d,%0d\n",
- // rcPaint.left, rcPaint.top, rcPaint.right, rcPaint.bottom);
- paintingAllText = true;
- if ((PWidget(wText))->window) {
- Surface *sw = Surface::Allocate();
- if (sw) {
- sw->Init(PWidget(wText)->window, PWidget(wText));
- Paint(sw, rcPaint);
- sw->Release();
- delete sw;
- }
- }
- paintState = notPainting;
-#else
wText.InvalidateAll();
-#endif
}
PRectangle ScintillaGTK::GetClientRectangle() {
@@ -1161,13 +1104,21 @@ void ScintillaGTK::SyncPaint(PRectangle rc) {
rcPaint = rc;
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
- if ((PWidget(wText))->window) {
+ if (PWindow(wText)) {
Surface *sw = Surface::Allocate();
if (sw) {
- sw->Init(PWidget(wText)->window, PWidget(wText));
+#if GTK_CHECK_VERSION(3,0,0)
+ cairo_t *cr = gdk_cairo_create(PWindow(wText));
+ sw->Init(cr, PWidget(wText));
+#else
+ sw->Init(PWindow(wText), PWidget(wText));
+#endif
Paint(sw, rc);
sw->Release();
delete sw;
+#if GTK_CHECK_VERSION(3,0,0)
+ cairo_destroy(cr);
+#endif
}
}
if (paintState == paintAbandoned) {
@@ -1183,50 +1134,8 @@ void ScintillaGTK::ScrollText(int linesToMove) {
// rc.left, rc.top, rc.right, rc.bottom);
GtkWidget *wi = PWidget(wText);
-#if GTK_MAJOR_VERSION < 2
- PRectangle rc = GetClientRectangle();
- GdkGC *gc = gdk_gc_new(wi->window);
-
- // Set up gc so we get GraphicsExposures from gdk_draw_pixmap
- // which calls XCopyArea
- gdk_gc_set_exposures(gc, TRUE);
-
- // Redraw exposed bit : scrolling upwards
- if (diff > 0) {
- gdk_draw_pixmap(wi->window,
- gc, wi->window,
- 0, diff,
- 0, 0,
- rc.Width()-1, rc.Height() - diff);
- SyncPaint(PRectangle(0, rc.Height() - diff,
- rc.Width(), rc.Height()+1));
-
- // Redraw exposed bit : scrolling downwards
- } else {
- gdk_draw_pixmap(wi->window,
- gc, wi->window,
- 0, 0,
- 0, -diff,
- rc.Width()-1, rc.Height() + diff);
- SyncPaint(PRectangle(0, 0, rc.Width(), -diff));
- }
-
- // Look for any graphics expose
- GdkEvent* event;
- while ((event = gdk_event_get_graphics_expose(wi->window)) != NULL) {
- gtk_widget_event(wi, event);
- if (event->expose.count == 0) {
- gdk_event_free(event);
- break;
- }
- gdk_event_free(event);
- }
-
- gdk_gc_unref(gc);
-#else
- gdk_window_scroll(wi->window, 0, -diff);
- gdk_window_process_updates(wi->window, FALSE);
-#endif
+ gdk_window_scroll(WindowFromWidget(wi), 0, -diff);
+ gdk_window_process_updates(WindowFromWidget(wi), FALSE);
}
void ScintillaGTK::SetVerticalScrollPos() {
@@ -1243,6 +1152,17 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
bool modified = false;
int pageScroll = LinesToScroll();
+#if GTK_CHECK_VERSION(3,0,0)
+ if (gtk_adjustment_get_upper(adjustmentv) != (nMax + 1) ||
+ gtk_adjustment_get_page_size(adjustmentv) != nPage ||
+ gtk_adjustment_get_page_increment(adjustmentv) != pageScroll) {
+ gtk_adjustment_set_upper(adjustmentv, nMax + 1);
+ gtk_adjustment_set_page_size(adjustmentv, nPage);
+ gtk_adjustment_set_page_increment(adjustmentv, pageScroll);
+ gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv));
+ modified = true;
+ }
+#else
if (GTK_ADJUSTMENT(adjustmentv)->upper != (nMax + 1) ||
GTK_ADJUSTMENT(adjustmentv)->page_size != nPage ||
GTK_ADJUSTMENT(adjustmentv)->page_increment != pageScroll) {
@@ -1252,6 +1172,7 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmentv));
modified = true;
}
+#endif
PRectangle rcText = GetTextRectangle();
int horizEndPreferred = scrollWidth;
@@ -1260,6 +1181,19 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
unsigned int pageWidth = rcText.Width();
unsigned int pageIncrement = pageWidth / 3;
unsigned int charWidth = vs.styles[STYLE_DEFAULT].aveCharWidth;
+#if GTK_CHECK_VERSION(3,0,0)
+ if (gtk_adjustment_get_upper(adjustmenth) != horizEndPreferred ||
+ gtk_adjustment_get_page_size(adjustmenth) != pageWidth ||
+ gtk_adjustment_get_page_increment(adjustmenth) != pageIncrement ||
+ gtk_adjustment_get_step_increment(adjustmenth) != charWidth) {
+ gtk_adjustment_set_upper(adjustmenth, horizEndPreferred);
+ gtk_adjustment_set_page_size(adjustmenth, pageWidth);
+ gtk_adjustment_set_page_increment(adjustmenth, pageIncrement);
+ gtk_adjustment_set_step_increment(adjustmenth, charWidth);
+ gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth));
+ modified = true;
+ }
+#else
if (GTK_ADJUSTMENT(adjustmenth)->upper != horizEndPreferred ||
GTK_ADJUSTMENT(adjustmenth)->page_size != pageWidth ||
GTK_ADJUSTMENT(adjustmenth)->page_increment != pageIncrement ||
@@ -1271,6 +1205,7 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
gtk_adjustment_changed(GTK_ADJUSTMENT(adjustmenth));
modified = true;
}
+#endif
return modified;
}
@@ -1280,37 +1215,21 @@ void ScintillaGTK::ReconfigureScrollBars() {
}
void ScintillaGTK::NotifyChange() {
-#if GLIB_MAJOR_VERSION < 2
- gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
- Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain));
-#else
g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0,
Platform::LongFromTwoShorts(GetCtrlID(), SCEN_CHANGE), PWidget(wMain));
-#endif
}
void ScintillaGTK::NotifyFocus(bool focus) {
-#if GLIB_MAJOR_VERSION < 2
- gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL],
- Platform::LongFromTwoShorts
- (GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain));
-#else
g_signal_emit(G_OBJECT(sci), scintilla_signals[COMMAND_SIGNAL], 0,
Platform::LongFromTwoShorts
(GetCtrlID(), focus ? SCEN_SETFOCUS : SCEN_KILLFOCUS), PWidget(wMain));
-#endif
}
void ScintillaGTK::NotifyParent(SCNotification scn) {
scn.nmhdr.hwndFrom = PWidget(wMain);
scn.nmhdr.idFrom = GetCtrlID();
-#if GLIB_MAJOR_VERSION < 2
- gtk_signal_emit(GTK_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL],
- GetCtrlID(), &scn);
-#else
g_signal_emit(G_OBJECT(sci), scintilla_signals[NOTIFY_SIGNAL], 0,
GetCtrlID(), &scn);
-#endif
}
void ScintillaGTK::NotifyKey(int key, int modifiers) {
@@ -1336,6 +1255,149 @@ const char *ScintillaGTK::CharacterSetID() const {
return ::CharacterSetID(vs.styles[STYLE_DEFAULT].characterSet);
}
+class CaseFolderUTF8 : public CaseFolderTable {
+public:
+ CaseFolderUTF8() {
+ StandardASCII();
+ }
+ virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
+ if ((lenMixed == 1) && (sizeFolded > 0)) {
+ folded[0] = mapping[static_cast<unsigned char>(mixed[0])];
+ return 1;
+ } else {
+ gchar *mapped = g_utf8_casefold(mixed, lenMixed);
+ size_t lenMapped = strlen(mapped);
+ if (lenMapped < sizeFolded) {
+ memcpy(folded, mapped, lenMapped);
+ } else {
+ lenMapped = 0;
+ }
+ g_free(mapped);
+ return lenMapped;
+ }
+ }
+};
+
+class CaseFolderDBCS : public CaseFolderTable {
+ const char *charSet;
+public:
+ CaseFolderDBCS(const char *charSet_) : charSet(charSet_) {
+ StandardASCII();
+ }
+ virtual size_t Fold(char *folded, size_t sizeFolded, const char *mixed, size_t lenMixed) {
+ if ((lenMixed == 1) && (sizeFolded > 0)) {
+ folded[0] = mapping[static_cast<unsigned char>(mixed[0])];
+ return 1;
+ } else if (*charSet) {
+ int convertedLength = lenMixed;
+ char *sUTF8 = ConvertText(&convertedLength, const_cast<char *>(mixed), lenMixed,
+ "UTF-8", charSet, false);
+ if (sUTF8) {
+ gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8));
+ size_t lenMapped = strlen(mapped);
+ if (lenMapped < sizeFolded) {
+ memcpy(folded, mapped, lenMapped);
+ } else {
+ folded[0] = '\0';
+ lenMapped = 1;
+ }
+ g_free(mapped);
+ delete []sUTF8;
+ return lenMapped;
+ }
+ }
+ // Something failed so return a single NUL byte
+ folded[0] = '\0';
+ return 1;
+ }
+};
+
+CaseFolder *ScintillaGTK::CaseFolderForEncoding() {
+ if (pdoc->dbcsCodePage == SC_CP_UTF8) {
+ return new CaseFolderUTF8();
+ } else {
+ const char *charSetBuffer = CharacterSetID();
+ if (charSetBuffer) {
+ if (pdoc->dbcsCodePage == 0) {
+ CaseFolderTable *pcf = new CaseFolderTable();
+ pcf->StandardASCII();
+ // Only for single byte encodings
+ for (int i=0x80; i<0x100; i++) {
+ char sCharacter[2] = "A";
+ sCharacter[0] = i;
+ int convertedLength = 1;
+ const char *sUTF8 = ConvertText(&convertedLength, sCharacter, 1,
+ "UTF-8", charSetBuffer, false);
+ if (sUTF8) {
+ gchar *mapped = g_utf8_casefold(sUTF8, strlen(sUTF8));
+ if (mapped) {
+ int mappedLength = strlen(mapped);
+ const char *mappedBack = ConvertText(&mappedLength, mapped,
+ mappedLength, charSetBuffer, "UTF-8", false, true);
+ if (mappedBack && (strlen(mappedBack) == 1) && (mappedBack[0] != sCharacter[0])) {
+ pcf->SetTranslation(sCharacter[0], mappedBack[0]);
+ }
+ delete []mappedBack;
+ g_free(mapped);
+ }
+ }
+ delete []sUTF8;
+ }
+ return pcf;
+ } else {
+ return new CaseFolderDBCS(charSetBuffer);
+ }
+ }
+ return 0;
+ }
+}
+
+std::string ScintillaGTK::CaseMapString(const std::string &s, int caseMapping) {
+ if (s.size() == 0)
+ return std::string();
+
+ if (caseMapping == cmSame)
+ return s;
+
+ const char *needsFree1 = 0; // Must be freed with delete []
+ const char *charSetBuffer = CharacterSetID();
+ const char *sUTF8 = s.c_str();
+ int rangeBytes = s.size();
+
+ int convertedLength = rangeBytes;
+ // Change text to UTF-8
+ if (!IsUnicodeMode()) {
+ // Need to convert
+ if (*charSetBuffer) {
+ sUTF8 = ConvertText(&convertedLength, const_cast<char *>(s.c_str()), rangeBytes,
+ "UTF-8", charSetBuffer, false);
+ needsFree1 = sUTF8;
+ }
+ }
+ gchar *mapped; // Must be freed with g_free
+ if (caseMapping == cmUpper) {
+ mapped = g_utf8_strup(sUTF8, convertedLength);
+ } else {
+ mapped = g_utf8_strdown(sUTF8, convertedLength);
+ }
+ int mappedLength = strlen(mapped);
+ char *mappedBack = mapped;
+
+ char *needsFree2 = 0; // Must be freed with delete []
+ if (!IsUnicodeMode()) {
+ if (*charSetBuffer) {
+ mappedBack = ConvertText(&mappedLength, mapped, mappedLength, charSetBuffer, "UTF-8", false);
+ needsFree2 = mappedBack;
+ }
+ }
+
+ std::string ret(mappedBack, mappedLength);
+ g_free(mapped);
+ delete []needsFree1;
+ delete []needsFree2;
+ return ret;
+}
+
int ScintillaGTK::KeyDefault(int key, int modifiers) {
if (!(modifiers & SCI_CTRL) && !(modifiers & SCI_ALT)) {
if (key < 256) {
@@ -1401,62 +1463,51 @@ void ScintillaGTK::CreateCallTipWindow(PRectangle rc) {
ct.wDraw = gtk_drawing_area_new();
GtkWidget *widcdrw = PWidget(ct.wDraw); // // No code inside the G_OBJECT macro
gtk_container_add(GTK_CONTAINER(PWidget(ct.wCallTip)), widcdrw);
-#if GLIB_MAJOR_VERSION < 2
- gtk_signal_connect(GTK_OBJECT(widcdrw), "expose_event",
- GtkSignalFunc(ScintillaGTK::ExposeCT), &ct);
- gtk_signal_connect(GTK_OBJECT(widcdrw), "button_press_event",
- GtkSignalFunc(ScintillaGTK::PressCT), static_cast<void *>(this));
+#if GTK_CHECK_VERSION(3,0,0)
+ g_signal_connect(G_OBJECT(widcdrw), "draw",
+ G_CALLBACK(ScintillaGTK::DrawCT), &ct);
#else
g_signal_connect(G_OBJECT(widcdrw), "expose_event",
G_CALLBACK(ScintillaGTK::ExposeCT), &ct);
+#endif
g_signal_connect(G_OBJECT(widcdrw), "button_press_event",
G_CALLBACK(ScintillaGTK::PressCT), static_cast<void *>(this));
-#endif
gtk_widget_set_events(widcdrw,
GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK);
}
- gtk_drawing_area_size(GTK_DRAWING_AREA(PWidget(ct.wDraw)),
- rc.Width(), rc.Height());
+ gtk_widget_set_size_request(PWidget(ct.wDraw), rc.Width(), rc.Height());
ct.wDraw.Show();
- if (PWidget(ct.wCallTip)->window) {
- gdk_window_resize(PWidget(ct.wCallTip)->window, rc.Width(), rc.Height());
+ if (PWindow(ct.wCallTip)) {
+ gdk_window_resize(PWindow(ct.wCallTip), rc.Width(), rc.Height());
}
}
void ScintillaGTK::AddToPopUp(const char *label, int cmd, bool enabled) {
- char fulllabel[200];
- strcpy(fulllabel, "/");
- strcat(fulllabel, label);
- GtkItemFactoryCallback menuSig = GtkItemFactoryCallback(PopUpCB);
- GtkItemFactoryEntry itemEntry = {
- fulllabel, NULL,
- menuSig,
- cmd,
- const_cast<gchar *>(label[0] ? "<Item>" : "<Separator>"),
-#if GTK_MAJOR_VERSION >= 2
- NULL
-#endif
- };
- gtk_item_factory_create_item(GTK_ITEM_FACTORY(popup.GetID()),
- &itemEntry, this, 1);
+ GtkWidget *menuItem;
+ if (label[0])
+ menuItem = gtk_menu_item_new_with_label(label);
+ else
+ menuItem = gtk_separator_menu_item_new();
+ gtk_menu_shell_append(GTK_MENU_SHELL(popup.GetID()), menuItem);
+ g_object_set_data(G_OBJECT(menuItem), "CmdNum", reinterpret_cast<void *>(cmd));
+ g_signal_connect(G_OBJECT(menuItem),"activate", G_CALLBACK(PopUpCB), this);
+
if (cmd) {
- GtkWidget *item = gtk_item_factory_get_widget_by_action(
- reinterpret_cast<GtkItemFactory *>(popup.GetID()), cmd);
- if (item)
- gtk_widget_set_sensitive(item, enabled);
+ if (menuItem)
+ gtk_widget_set_sensitive(menuItem, enabled);
}
}
bool ScintillaGTK::OwnPrimarySelection() {
return ((gdk_selection_owner_get(GDK_SELECTION_PRIMARY)
- == GTK_WIDGET(PWidget(wMain))->window) &&
- (GTK_WIDGET(PWidget(wMain))->window != NULL));
+ == PWindow(wMain)) &&
+ (PWindow(wMain) != NULL));
}
void ScintillaGTK::ClaimSelection() {
// X Windows has a 'primary selection' as well as the clipboard.
// Whenever the user selects some text, we become the primary selection
- if (!sel.Empty() && GTK_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
+ if (!sel.Empty() && IS_WIDGET_REALIZED(GTK_WIDGET(PWidget(wMain)))) {
primarySelection = true;
gtk_selection_owner_set(GTK_WIDGET(PWidget(wMain)),
GDK_SELECTION_PRIMARY, GDK_CURRENT_TIME);
@@ -1471,11 +1522,23 @@ void ScintillaGTK::ClaimSelection() {
}
}
+#if GTK_CHECK_VERSION(3,0,0)
+static const guchar *DataOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_data(sd); }
+static gint LengthOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_length(sd); }
+static GdkAtom TypeOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_data_type(sd); }
+static GdkAtom SelectionOfGSD(GtkSelectionData *sd) { return gtk_selection_data_get_selection(sd); }
+#else
+static const guchar *DataOfGSD(GtkSelectionData *sd) { return sd->data; }
+static gint LengthOfGSD(GtkSelectionData *sd) { return sd->length; }
+static GdkAtom TypeOfGSD(GtkSelectionData *sd) { return sd->type; }
+static GdkAtom SelectionOfGSD(GtkSelectionData *sd) { return sd->selection; }
+#endif
+
// Detect rectangular text, convert line ends to current mode, convert from or to UTF-8
void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, SelectionText &selText) {
- char *data = reinterpret_cast<char *>(selectionData->data);
- int len = selectionData->length;
- GdkAtom selectionTypeData = selectionData->type;
+ const char *data = reinterpret_cast<const char *>(DataOfGSD(selectionData));
+ int len = LengthOfGSD(selectionData);
+ GdkAtom selectionTypeData = TypeOfGSD(selectionData);
// Return empty string if selection is not a string
if ((selectionTypeData != GDK_TARGET_STRING) && (selectionTypeData != atomUTF8)) {
@@ -1491,6 +1554,8 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio
isRectangular = ::IsClipboardFormatAvailable(cfColumnSelect) != 0;
#else
isRectangular = ((len > 2) && (data[len - 1] == 0 && data[len - 2] == '\n'));
+ if (isRectangular)
+ len--; // Forget the extra '\0'
#endif
char *dest;
@@ -1510,35 +1575,32 @@ void ScintillaGTK::GetGtkSelectionText(GtkSelectionData *selectionData, Selectio
} else { // UTF-8
dest = Document::TransformLineEnds(&len, data, len, pdoc->eolMode);
selText.Set(dest, len, SC_CP_UTF8, 0, isRectangular, false);
-#ifdef USE_CONVERTER
const char *charSetBuffer = CharacterSetID();
if (!IsUnicodeMode() && *charSetBuffer) {
-//fprintf(stderr, "Convert to locale %s\n", CharacterSetID());
- // Convert to locale
- dest = ConvertText(&len, selText.s, selText.len, charSetBuffer, "UTF-8", true);
- selText.Set(dest, len, pdoc->dbcsCodePage,
- vs.styles[STYLE_DEFAULT].characterSet, selText.rectangular, false);
+ // Convert to locale
+ dest = ConvertText(&len, selText.s, selText.len, charSetBuffer, "UTF-8", true);
+ selText.Set(dest, len, pdoc->dbcsCodePage,
+ vs.styles[STYLE_DEFAULT].characterSet, selText.rectangular, false);
}
-#endif
}
}
void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
try {
- if ((selection_data->selection == atomClipboard) ||
- (selection_data->selection == GDK_SELECTION_PRIMARY)) {
- if ((atomSought == atomUTF8) && (selection_data->length <= 0)) {
+ if ((SelectionOfGSD(selection_data) == atomClipboard) ||
+ (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY)) {
+ if ((atomSought == atomUTF8) && (LengthOfGSD(selection_data) <= 0)) {
atomSought = atomString;
gtk_selection_convert(GTK_WIDGET(PWidget(wMain)),
- selection_data->selection, atomSought, GDK_CURRENT_TIME);
- } else if ((selection_data->length > 0) &&
- ((selection_data->type == GDK_TARGET_STRING) || (selection_data->type == atomUTF8))) {
+ SelectionOfGSD(selection_data), atomSought, GDK_CURRENT_TIME);
+ } else if ((LengthOfGSD(selection_data) > 0) &&
+ ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8))) {
SelectionText selText;
GetGtkSelectionText(selection_data, selText);
UndoGroup ug(pdoc);
- if (selection_data->selection != GDK_SELECTION_PRIMARY) {
- ClearSelection();
+ if (SelectionOfGSD(selection_data) != GDK_SELECTION_PRIMARY) {
+ ClearSelection(multiPasteMode == SC_MULTIPASTE_EACH);
}
SelectionPosition selStart = sel.IsRectangular() ?
sel.Rectangular().Start() :
@@ -1547,10 +1609,7 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
if (selText.rectangular) {
PasteRectangular(selStart, selText.s, selText.len);
} else {
- selStart = SelectionPosition(InsertSpace(selStart.Position(), selStart.VirtualSpace()));
- if (pdoc->InsertString(selStart.Position(),selText.s, selText.len)) {
- SetEmptySelection(selStart.Position() + selText.len);
- }
+ InsertPaste(selStart, selText.s, selText.len);
}
EnsureCaretVisible();
}
@@ -1565,19 +1624,19 @@ void ScintillaGTK::ReceivedSelection(GtkSelectionData *selection_data) {
void ScintillaGTK::ReceivedDrop(GtkSelectionData *selection_data) {
dragWasDropped = true;
- if (selection_data->type == atomUriList || selection_data->type == atomDROPFILES_DND) {
- char *ptr = new char[selection_data->length + 1];
- ptr[selection_data->length] = '\0';
- memcpy(ptr, selection_data->data, selection_data->length);
+ if (TypeOfGSD(selection_data) == atomUriList || TypeOfGSD(selection_data) == atomDROPFILES_DND) {
+ char *ptr = new char[LengthOfGSD(selection_data) + 1];
+ ptr[LengthOfGSD(selection_data)] = '\0';
+ memcpy(ptr, DataOfGSD(selection_data), LengthOfGSD(selection_data));
NotifyURIDropped(ptr);
delete []ptr;
- } else if ((selection_data->type == GDK_TARGET_STRING) || (selection_data->type == atomUTF8)) {
- if (selection_data->length > 0) {
+ } else if ((TypeOfGSD(selection_data) == GDK_TARGET_STRING) || (TypeOfGSD(selection_data) == atomUTF8)) {
+ if (TypeOfGSD(selection_data) > 0) {
SelectionText selText;
GetGtkSelectionText(selection_data, selText);
DropAt(posDrop, selText.s, false, selText.rectangular);
}
- } else if (selection_data->length > 0) {
+ } else if (LengthOfGSD(selection_data) > 0) {
//~ fprintf(stderr, "ReceivedDrop other %p\n", static_cast<void *>(selection_data->type));
}
Redraw();
@@ -1600,7 +1659,6 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se
}
#endif
-#if GTK_MAJOR_VERSION >= 2
// Convert text to utf8 if it isn't already
SelectionText *converted = 0;
if ((text->codePage != SC_CP_UTF8) && (info == TARGET_UTF8_STRING)) {
@@ -1637,64 +1695,6 @@ void ScintillaGTK::GetSelection(GtkSelectionData *selection_data, guint info, Se
}
delete converted;
-#else /* Gtk 1 */
- char *selBuffer = text->s;
-
- char *tmputf = 0;
- if ((info == TARGET_UTF8_STRING) || (info == TARGET_STRING)) {
- int len = strlen(selBuffer);
-#ifdef USE_CONVERTER
- // Possible character set conversion
- const char *charSetBuffer = ::CharacterSetID(text->characterSet);
- if (info == TARGET_UTF8_STRING) {
- //fprintf(stderr, "Copy to clipboard as UTF-8\n");
- if (text->codePage != SC_CP_UTF8) {
- // Convert to UTF-8
- //fprintf(stderr, "Convert to UTF-8 from %s\n", charSetBuffer);
- tmputf = ConvertText(&len, selBuffer, len, "UTF-8", charSetBuffer, false);
- selBuffer = tmputf;
- }
- } else if (info == TARGET_STRING) {
- if (text->codePage == SC_CP_UTF8) {
- //fprintf(stderr, "Convert to locale %s\n", charSetBuffer);
- // Convert to locale
- tmputf = ConvertText(&len, selBuffer, len, charSetBuffer, "UTF-8", true);
- selBuffer = tmputf;
- }
- }
-#endif
-
- // Here is a somewhat evil kludge.
- // As I can not work out how to store data on the clipboard in multiple formats
- // and need some way to mark the clipping as being stream or rectangular,
- // the terminating \0 is included in the length for rectangular clippings.
- // All other tested aplications behave benignly by ignoring the \0.
- // The #if is here because on Windows cfColumnSelect clip entry is used
- // instead as standard indicator of rectangularness (so no need to kludge)
-#if PLAT_GTK_WIN32 == 0
- if (text->rectangular)
- len++;
-#endif
- gtk_selection_data_set(selection_data,
- (info == TARGET_STRING) ?
- static_cast<GdkAtom>(GDK_SELECTION_TYPE_STRING) : atomUTF8,
- 8, reinterpret_cast<unsigned char *>(selBuffer),
- len);
- } else if ((info == TARGET_TEXT) || (info == TARGET_COMPOUND_TEXT)) {
- guchar *text;
- GdkAtom encoding;
- gint format;
- gint new_length;
-
- gdk_string_to_compound_text(reinterpret_cast<char *>(selBuffer),
- &encoding, &format, &text, &new_length);
- gtk_selection_data_set(selection_data, encoding, format, text, new_length);
- gdk_free_compound_text(text);
- }
-
- delete []tmputf;
-#endif /* Gtk >= 2 */
-
#if PLAT_GTK_WIN32
delete newline_normalized;
#endif
@@ -1744,8 +1744,16 @@ void ScintillaGTK::Resize(int width, int height) {
//printf("Resize %d %d\n", width, height);
// Not always needed, but some themes can have different sizes of scrollbars
+#if GTK_CHECK_VERSION(3,0,0)
+ GtkRequisition requisition;
+ gtk_widget_get_requisition(PWidget(scrollbarv), &requisition);
+ scrollBarWidth = requisition.width;
+ gtk_widget_get_requisition(PWidget(scrollbarh), &requisition);
+ scrollBarHeight = requisition.height;
+#else
scrollBarWidth = GTK_WIDGET(PWidget(scrollbarv))->requisition.width;
scrollBarHeight = GTK_WIDGET(PWidget(scrollbarh))->requisition.height;
+#endif
// These allocations should never produce negative sizes as they would wrap around to huge
// unsigned numbers inside GTK+ causing warnings.
@@ -1753,16 +1761,13 @@ void ScintillaGTK::Resize(int width, int height) {
int horizontalScrollBarHeight = scrollBarHeight;
if (!showSBHorizontal)
horizontalScrollBarHeight = 0;
- int verticalScrollBarHeight = scrollBarWidth;
- if (!verticalScrollBarVisible)
- verticalScrollBarHeight = 0;
GtkAllocation alloc;
if (showSBHorizontal) {
gtk_widget_show(GTK_WIDGET(PWidget(scrollbarh)));
alloc.x = 0;
alloc.y = height - scrollBarHeight;
- alloc.width = Platform::Maximum(1, width - scrollBarWidth) + 1;
+ alloc.width = Platform::Maximum(1, width - scrollBarWidth);
alloc.height = horizontalScrollBarHeight;
gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarh)), &alloc);
} else {
@@ -1774,14 +1779,14 @@ void ScintillaGTK::Resize(int width, int height) {
alloc.x = width - scrollBarWidth;
alloc.y = 0;
alloc.width = scrollBarWidth;
- alloc.height = Platform::Maximum(1, height - scrollBarHeight) + 1;
+ alloc.height = Platform::Maximum(1, height - scrollBarHeight);
if (!showSBHorizontal)
alloc.height += scrollBarWidth-1;
gtk_widget_size_allocate(GTK_WIDGET(PWidget(scrollbarv)), &alloc);
} else {
gtk_widget_hide(GTK_WIDGET(PWidget(scrollbarv)));
}
- if (GTK_WIDGET_MAPPED(PWidget(wMain))) {
+ if (IS_WIDGET_MAPPED(PWidget(wMain))) {
ChangeSize();
}
@@ -1796,10 +1801,16 @@ void ScintillaGTK::Resize(int width, int height) {
gtk_widget_size_allocate(GTK_WIDGET(PWidget(wText)), &alloc);
}
-static void SetAdjustmentValue(GtkObject *object, int value) {
+static void SetAdjustmentValue(GtkAdjustment *object, int value) {
GtkAdjustment *adjustment = GTK_ADJUSTMENT(object);
+#if GTK_CHECK_VERSION(3,0,0)
+ int maxValue = static_cast<int>(
+ gtk_adjustment_get_upper(adjustment) - gtk_adjustment_get_page_size(adjustment));
+#else
int maxValue = static_cast<int>(
adjustment->upper - adjustment->page_size);
+#endif
+
if (value > maxValue)
value = maxValue;
if (value < 0)
@@ -1817,7 +1828,7 @@ static int modifierTranslated(int sciModifier) {
return GDK_MOD1_MASK;
case SCMOD_SUPER:
return GDK_MOD4_MASK;
- default:
+ default:
return 0;
}
}
@@ -1854,21 +1865,24 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) {
(event->state & modifierTranslated(rectangularSelectionModifier)) != 0);
} else if (event->button == 2) {
// Grab the primary selection if it exists
- SelectionPosition pos = SPositionFromLocation(pt);
+ SelectionPosition pos = SPositionFromLocation(pt, false, false, UserVirtualSpace());
if (OwnPrimarySelection() && primary.s == NULL)
CopySelectionRange(&primary);
+ sel.Clear();
SetSelection(pos, pos);
atomSought = atomUTF8;
gtk_selection_convert(GTK_WIDGET(PWidget(wMain)), GDK_SELECTION_PRIMARY,
atomSought, event->time);
} else if (event->button == 3) {
+ if (!PointInSelection(pt))
+ SetEmptySelection(PositionFromLocation(pt));
if (displayPopupMenu) {
// PopUp menu
// Convert to screen
int ox = 0;
int oy = 0;
- gdk_window_get_origin(PWidget(wMain)->window, &ox, &oy);
+ gdk_window_get_origin(PWindow(wMain), &ox, &oy);
ContextMenu(Point(pt.x + ox, pt.y + oy));
} else {
return FALSE;
@@ -1889,15 +1903,11 @@ gint ScintillaGTK::PressThis(GdkEventButton *event) {
} catch (...) {
errorStatus = SC_STATUS_FAILURE;
}
-#if GTK_MAJOR_VERSION >= 2
return TRUE;
-#else
- return FALSE;
-#endif
}
gint ScintillaGTK::Press(GtkWidget *widget, GdkEventButton *event) {
- if (event->window != widget->window)
+ if (event->window != WindowFromWidget(widget))
return FALSE;
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
return sciThis->PressThis(event);
@@ -1915,7 +1925,7 @@ gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) {
pt.y = int(event->y);
//Platform::DebugPrintf("Up %x %x %d %d %d\n",
// sciThis,event->window,event->time, pt.x, pt.y);
- if (event->window != PWidget(sciThis->wMain)->window)
+ if (event->window != PWindow(sciThis->wMain))
// If mouse released on scroll bar then the position is relative to the
// scrollbar, not the drawing window so just repeat the most recent point.
pt = sciThis->ptMouseLast;
@@ -1929,7 +1939,6 @@ gint ScintillaGTK::MouseRelease(GtkWidget *widget, GdkEventButton *event) {
// win32gtk and GTK >= 2 use SCROLL_* events instead of passing the
// button4/5/6/7 events to the GTK app
-#if PLAT_GTK_WIN32 || (GTK_MAJOR_VERSION >= 2)
gint ScintillaGTK::ScrollEvent(GtkWidget *widget,
GdkEventScroll *event) {
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
@@ -2006,13 +2015,12 @@ gint ScintillaGTK::ScrollEvent(GtkWidget *widget,
}
return FALSE;
}
-#endif
gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) {
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
try {
//Platform::DebugPrintf("Motion %x %d\n",sciThis,event->time);
- if (event->window != widget->window)
+ if (event->window != WindowFromWidget(widget))
return FALSE;
int x = 0;
int y = 0;
@@ -2037,6 +2045,75 @@ gint ScintillaGTK::Motion(GtkWidget *widget, GdkEventMotion *event) {
// Map the keypad keys to their equivalent functions
static int KeyTranslate(int keyIn) {
switch (keyIn) {
+#if GTK_CHECK_VERSION(3,0,0)
+ case GDK_KEY_ISO_Left_Tab:
+ return SCK_TAB;
+ case GDK_KEY_KP_Down:
+ return SCK_DOWN;
+ case GDK_KEY_KP_Up:
+ return SCK_UP;
+ case GDK_KEY_KP_Left:
+ return SCK_LEFT;
+ case GDK_KEY_KP_Right:
+ return SCK_RIGHT;
+ case GDK_KEY_KP_Home:
+ return SCK_HOME;
+ case GDK_KEY_KP_End:
+ return SCK_END;
+ case GDK_KEY_KP_Page_Up:
+ return SCK_PRIOR;
+ case GDK_KEY_KP_Page_Down:
+ return SCK_NEXT;
+ case GDK_KEY_KP_Delete:
+ return SCK_DELETE;
+ case GDK_KEY_KP_Insert:
+ return SCK_INSERT;
+ case GDK_KEY_KP_Enter:
+ return SCK_RETURN;
+
+ case GDK_KEY_Down:
+ return SCK_DOWN;
+ case GDK_KEY_Up:
+ return SCK_UP;
+ case GDK_KEY_Left:
+ return SCK_LEFT;
+ case GDK_KEY_Right:
+ return SCK_RIGHT;
+ case GDK_KEY_Home:
+ return SCK_HOME;
+ case GDK_KEY_End:
+ return SCK_END;
+ case GDK_KEY_Page_Up:
+ return SCK_PRIOR;
+ case GDK_KEY_Page_Down:
+ return SCK_NEXT;
+ case GDK_KEY_Delete:
+ return SCK_DELETE;
+ case GDK_KEY_Insert:
+ return SCK_INSERT;
+ case GDK_KEY_Escape:
+ return SCK_ESCAPE;
+ case GDK_KEY_BackSpace:
+ return SCK_BACK;
+ case GDK_KEY_Tab:
+ return SCK_TAB;
+ case GDK_KEY_Return:
+ return SCK_RETURN;
+ case GDK_KEY_KP_Add:
+ return SCK_ADD;
+ case GDK_KEY_KP_Subtract:
+ return SCK_SUBTRACT;
+ case GDK_KEY_KP_Divide:
+ return SCK_DIVIDE;
+ case GDK_KEY_Super_L:
+ return SCK_WIN;
+ case GDK_KEY_Super_R:
+ return SCK_RWIN;
+ case GDK_KEY_Menu:
+ return SCK_MENU;
+
+#else
+
case GDK_ISO_Left_Tab:
return SCK_TAB;
case GDK_KP_Down:
@@ -2102,6 +2179,7 @@ static int KeyTranslate(int keyIn) {
return SCK_RWIN;
case GDK_Menu:
return SCK_MENU;
+#endif
default:
return keyIn;
}
@@ -2111,11 +2189,9 @@ gboolean ScintillaGTK::KeyThis(GdkEventKey *event) {
try {
//fprintf(stderr, "SC-key: %d %x [%s]\n",
// event->keyval, event->state, (event->length > 0) ? event->string : "empty");
-#if GTK_MAJOR_VERSION >= 2
if (gtk_im_context_filter_keypress(im_context, event)) {
return 1;
}
-#endif
if (!event->keyval) {
return true;
}
@@ -2126,16 +2202,16 @@ gboolean ScintillaGTK::KeyThis(GdkEventKey *event) {
guint key = event->keyval;
if (ctrl && (key < 128))
key = toupper(key);
+#if GTK_CHECK_VERSION(3,0,0)
+ else if (!ctrl && (key >= GDK_KEY_KP_Multiply && key <= GDK_KEY_KP_9))
+#else
else if (!ctrl && (key >= GDK_KP_Multiply && key <= GDK_KP_9))
+#endif
key &= 0x7F;
// Hack for keys over 256 and below command keys but makes Hungarian work.
// This will have to change for Unicode
else if (key >= 0xFE00)
key = KeyTranslate(key);
-#if GTK_MAJOR_VERSION < 2
- else if (!IsUnicodeMode() && (key >= 0x100) && (key < 0x1000))
- key &= 0xff;
-#endif
bool consumed = false;
bool added = KeyDown(key, shift, ctrl, alt, &consumed) != 0;
@@ -2165,7 +2241,6 @@ gboolean ScintillaGTK::KeyRelease(GtkWidget *, GdkEventKey * /*event*/) {
return FALSE;
}
-#if GTK_MAJOR_VERSION >= 2
gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose) {
try {
gchar *str;
@@ -2176,12 +2251,13 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
PangoLayout *layout = gtk_widget_create_pango_layout(PWidget(wText), str);
pango_layout_set_attributes(layout, attrs);
+#ifndef USE_CAIRO
GdkGC *gc = gdk_gc_new(widget->window);
GdkColor color[2] = { {0, 0x0000, 0x0000, 0x0000},
{0, 0xffff, 0xffff, 0xffff}
};
- gdk_color_alloc(gdk_colormap_get_system(), color);
- gdk_color_alloc(gdk_colormap_get_system(), color + 1);
+ gdk_colormap_alloc_color(gdk_colormap_get_system(), color, FALSE, TRUE);
+ gdk_colormap_alloc_color(gdk_colormap_get_system(), color + 1, FALSE, TRUE);
gdk_gc_set_foreground(gc, color + 1);
gdk_draw_rectangle(widget->window, gc, TRUE, ose->area.x, ose->area.y,
@@ -2190,8 +2266,8 @@ gboolean ScintillaGTK::ExposePreeditThis(GtkWidget *widget, GdkEventExpose *ose)
gdk_gc_set_foreground(gc, color);
gdk_gc_set_background(gc, color + 1);
gdk_draw_layout(widget->window, gc, 0, 0, layout);
-
- gdk_gc_unref(gc);
+ g_object_unref(gc);
+#endif
g_free(str);
pango_attr_list_unref(attrs);
g_object_unref(layout);
@@ -2256,7 +2332,7 @@ void ScintillaGTK::PreeditChangedThis() {
g_object_unref(layout);
gint x, y;
- gdk_window_get_origin((PWidget(wText))->window, &x, &y);
+ gdk_window_get_origin(PWindow(wText), &x, &y);
Point pt = PointMainCaret();
if (pt.x < 0)
@@ -2281,26 +2357,23 @@ void ScintillaGTK::PreeditChangedThis() {
void ScintillaGTK::PreeditChanged(GtkIMContext *, ScintillaGTK *sciThis) {
sciThis->PreeditChangedThis();
}
-#endif
-
-gint ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void*) {
- if (widget->window != NULL)
- gdk_window_set_back_pixmap(widget->window, NULL, FALSE);
- return FALSE;
-}
-gint ScintillaGTK::RealizeText(GtkWidget *widget, void*) {
- if (widget->window != NULL)
- gdk_window_set_back_pixmap(widget->window, NULL, FALSE);
- return FALSE;
+void ScintillaGTK::StyleSetText(GtkWidget *widget, GtkStyle *, void*) {
+ RealizeText(widget, NULL);
}
-#if GLIB_MAJOR_VERSION < 2
-void ScintillaGTK::Destroy(GtkObject *object)
+void ScintillaGTK::RealizeText(GtkWidget *widget, void*) {
+ // Set NULL background to avoid automatic clearing so Scintilla responsible for all drawing
+ if (WindowFromWidget(widget)) {
+#if GTK_CHECK_VERSION(3,0,0)
+ gdk_window_set_background_pattern(WindowFromWidget(widget), NULL);
#else
-void ScintillaGTK::Destroy(GObject *object)
+ gdk_window_set_back_pixmap(WindowFromWidget(widget), NULL, FALSE);
#endif
-{
+ }
+}
+
+void ScintillaGTK::Destroy(GObject *object) {
try {
ScintillaObject *scio = reinterpret_cast<ScintillaObject *>(object);
// This avoids a double destruction
@@ -2310,13 +2383,6 @@ void ScintillaGTK::Destroy(GObject *object)
//Platform::DebugPrintf("Destroying %x %x\n", sciThis, object);
sciThis->Finalise();
-#if GLIB_MAJOR_VERSION < 2
- if (GTK_OBJECT_CLASS(parent_class)->destroy)
- (* GTK_OBJECT_CLASS(parent_class)->destroy)(object);
-#else
- // IS ANYTHING NEEDED ?
-#endif
-
delete sciThis;
scio->pscin = 0;
} catch (...) {
@@ -2324,56 +2390,34 @@ void ScintillaGTK::Destroy(GObject *object)
}
}
-static void DrawChild(GtkWidget *widget, GdkRectangle *area) {
- GdkRectangle areaIntersect;
- if (widget &&
- GTK_WIDGET_DRAWABLE(widget) &&
- gtk_widget_intersect(widget, area, &areaIntersect)) {
- gtk_widget_draw(widget, &areaIntersect);
- }
-}
-
-void ScintillaGTK::Draw(GtkWidget *widget, GdkRectangle *area) {
- ScintillaGTK *sciThis = ScintillaFromWidget(widget);
- try {
- //Platform::DebugPrintf("Draw %p %0d,%0d %0d,%0d\n", widget, area->x, area->y, area->width, area->height);
- PRectangle rcPaint(area->x, area->y, area->x + area->width, area->y + area->height);
- sciThis->SyncPaint(rcPaint);
- if (GTK_WIDGET_DRAWABLE(PWidget(sciThis->wMain))) {
- DrawChild(PWidget(sciThis->scrollbarh), area);
- DrawChild(PWidget(sciThis->scrollbarv), area);
- }
+#if GTK_CHECK_VERSION(3,0,0)
-#ifdef INTERNATIONAL_INPUT
- Point pt = sciThis->PointMainCaret();
- pt.y += sciThis->vs.lineHeight - 2;
- if (pt.x < 0) pt.x = 0;
- if (pt.y < 0) pt.y = 0;
- CursorMoved(widget, pt.x, pt.y, sciThis);
-#endif
- } catch (...) {
- sciThis->errorStatus = SC_STATUS_FAILURE;
- }
-}
-
-gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
+gboolean ScintillaGTK::DrawTextThis(cairo_t *cr) {
try {
paintState = painting;
- rcPaint.left = ose->area.x;
- rcPaint.top = ose->area.y;
- rcPaint.right = ose->area.x + ose->area.width;
- rcPaint.bottom = ose->area.y + ose->area.height;
+ rcPaint = GetClientRectangle();
PLATFORM_ASSERT(rgnUpdate == NULL);
-#if GTK_MAJOR_VERSION >= 2
- rgnUpdate = gdk_region_copy(ose->region);
-#endif
+ rgnUpdate = cairo_copy_clip_rectangle_list(cr);
+ if (rgnUpdate && rgnUpdate->status != CAIRO_STATUS_SUCCESS) {
+ // If not successful then ignore
+ fprintf(stderr, "DrawTextThis failed to copy update region %d [%d]\n", rgnUpdate->status, rgnUpdate->num_rectangles);
+ cairo_rectangle_list_destroy(rgnUpdate);
+ rgnUpdate = 0;
+ }
+
+ double x1, y1, x2, y2;
+ cairo_clip_extents(cr, &x1, &y1, &x2, &y2);
+ rcPaint.left = x1;
+ rcPaint.top = y1;
+ rcPaint.right = x2;
+ rcPaint.bottom = y2;
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
Surface *surfaceWindow = Surface::Allocate();
if (surfaceWindow) {
- surfaceWindow->Init(PWidget(wText)->window, PWidget(wText));
+ surfaceWindow->Init(cr, PWidget(wText));
Paint(surfaceWindow, rcPaint);
surfaceWindow->Release();
delete surfaceWindow;
@@ -2385,9 +2429,10 @@ gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
paintState = notPainting;
if (rgnUpdate) {
- gdk_region_destroy(rgnUpdate);
+ cairo_rectangle_list_destroy(rgnUpdate);
}
rgnUpdate = 0;
+ paintState = notPainting;
} catch (...) {
errorStatus = SC_STATUS_FAILURE;
}
@@ -2395,24 +2440,31 @@ gint ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
return FALSE;
}
-gint ScintillaGTK::ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis) {
- return sciThis->ExposeTextThis(widget, ose);
+gboolean ScintillaGTK::DrawText(GtkWidget *, cairo_t *cr, ScintillaGTK *sciThis) {
+ return sciThis->DrawTextThis(cr);
}
-gint ScintillaGTK::ExposeMain(GtkWidget *widget, GdkEventExpose *ose) {
- ScintillaGTK *sciThis = ScintillaFromWidget(widget);
- //Platform::DebugPrintf("Expose Main %0d,%0d %0d,%0d\n",
- //ose->area.x, ose->area.y, ose->area.width, ose->area.height);
- return sciThis->Expose(widget, ose);
+gboolean ScintillaGTK::DrawThis(cairo_t *cr) {
+ try {
+ gtk_container_propagate_draw(
+ GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), cr);
+ gtk_container_propagate_draw(
+ GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), cr);
+ } catch (...) {
+ errorStatus = SC_STATUS_FAILURE;
+ }
+ return FALSE;
}
-gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
- try {
- //fprintf(stderr, "Expose %0d,%0d %0d,%0d\n",
- //ose->area.x, ose->area.y, ose->area.width, ose->area.height);
+gboolean ScintillaGTK::DrawMain(GtkWidget *widget, cairo_t *cr) {
+ ScintillaGTK *sciThis = ScintillaFromWidget(widget);
+ return sciThis->DrawThis(cr);
+}
-#if GTK_MAJOR_VERSION < 2
+#else
+gboolean ScintillaGTK::ExposeTextThis(GtkWidget * /*widget*/, GdkEventExpose *ose) {
+ try {
paintState = painting;
rcPaint.left = ose->area.x;
@@ -2420,26 +2472,14 @@ gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
rcPaint.right = ose->area.x + ose->area.width;
rcPaint.bottom = ose->area.y + ose->area.height;
+ PLATFORM_ASSERT(rgnUpdate == NULL);
+ rgnUpdate = gdk_region_copy(ose->region);
PRectangle rcClient = GetClientRectangle();
paintingAllText = rcPaint.Contains(rcClient);
Surface *surfaceWindow = Surface::Allocate();
if (surfaceWindow) {
- surfaceWindow->Init(PWidget(wMain)->window, PWidget(wMain));
-
- // Fill the corner between the scrollbars
- if (verticalScrollBarVisible) {
- if (horizontalScrollBarVisible && (wrapState == eWrapNone)) {
- PRectangle rcCorner = wMain.GetClientPosition();
- rcCorner.left = rcCorner.right - scrollBarWidth + 1;
- rcCorner.top = rcCorner.bottom - scrollBarHeight + 1;
- //fprintf(stderr, "Corner %0d,%0d %0d,%0d\n",
- //rcCorner.left, rcCorner.top, rcCorner.right, rcCorner.bottom);
- surfaceWindow->FillRectangle(rcCorner,
- vs.styles[STYLE_LINENUMBER].back.allocated);
- }
- }
-
- //Paint(surfaceWindow, rcPaint);
+ surfaceWindow->Init(PWindow(wText), PWidget(wText));
+ Paint(surfaceWindow, rcPaint);
surfaceWindow->Release();
delete surfaceWindow;
}
@@ -2449,13 +2489,38 @@ gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
}
paintState = notPainting;
-#else
- // For GTK+ 2, the text is painted in ExposeText
+ if (rgnUpdate) {
+ gdk_region_destroy(rgnUpdate);
+ }
+ rgnUpdate = 0;
+ } catch (...) {
+ errorStatus = SC_STATUS_FAILURE;
+ }
+
+ return FALSE;
+}
+
+gboolean ScintillaGTK::ExposeText(GtkWidget *widget, GdkEventExpose *ose, ScintillaGTK *sciThis) {
+ return sciThis->ExposeTextThis(widget, ose);
+}
+
+gboolean ScintillaGTK::ExposeMain(GtkWidget *widget, GdkEventExpose *ose) {
+ ScintillaGTK *sciThis = ScintillaFromWidget(widget);
+ //Platform::DebugPrintf("Expose Main %0d,%0d %0d,%0d\n",
+ //ose->area.x, ose->area.y, ose->area.width, ose->area.height);
+ return sciThis->Expose(widget, ose);
+}
+
+gboolean ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
+ try {
+ //fprintf(stderr, "Expose %0d,%0d %0d,%0d\n",
+ //ose->area.x, ose->area.y, ose->area.width, ose->area.height);
+
+ // The text is painted in ExposeText
gtk_container_propagate_expose(
GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarh), ose);
gtk_container_propagate_expose(
GTK_CONTAINER(PWidget(wMain)), PWidget(scrollbarv), ose);
-#endif
} catch (...) {
errorStatus = SC_STATUS_FAILURE;
@@ -2463,9 +2528,15 @@ gint ScintillaGTK::Expose(GtkWidget *, GdkEventExpose *ose) {
return FALSE;
}
+#endif
+
void ScintillaGTK::ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
try {
+#if GTK_CHECK_VERSION(3,0,0)
+ sciThis->ScrollTo(static_cast<int>(gtk_adjustment_get_value(adj)), false);
+#else
sciThis->ScrollTo(static_cast<int>(adj->value), false);
+#endif
} catch (...) {
sciThis->errorStatus = SC_STATUS_FAILURE;
}
@@ -2473,7 +2544,11 @@ void ScintillaGTK::ScrollSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
void ScintillaGTK::ScrollHSignal(GtkAdjustment *adj, ScintillaGTK *sciThis) {
try {
+#if GTK_CHECK_VERSION(3,0,0)
+ sciThis->HorizontalScrollTo(static_cast<int>(gtk_adjustment_get_value(adj) * 2));
+#else
sciThis->HorizontalScrollTo(static_cast<int>(adj->value * 2));
+#endif
} catch (...) {
sciThis->errorStatus = SC_STATUS_FAILURE;
}
@@ -2491,7 +2566,7 @@ void ScintillaGTK::SelectionGet(GtkWidget *widget,
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
try {
//Platform::DebugPrintf("Selection get\n");
- if (selection_data->selection == GDK_SELECTION_PRIMARY) {
+ if (SelectionOfGSD(selection_data) == GDK_SELECTION_PRIMARY) {
if (sciThis->primary.s == NULL) {
sciThis->CopySelectionRange(&sciThis->primary);
}
@@ -2511,15 +2586,11 @@ gint ScintillaGTK::SelectionClear(GtkWidget *widget, GdkEventSelection *selectio
ScintillaGTK *sciThis = ScintillaFromWidget(widget);
//Platform::DebugPrintf("Selection clear\n");
sciThis->UnclaimSelection(selection_event);
- return gtk_selection_clear(widget, selection_event);
-}
-
-#if GTK_MAJOR_VERSION < 2
-gint ScintillaGTK::SelectionNotify(GtkWidget *widget, GdkEventSelection *selection_event) {
- //Platform::DebugPrintf("Selection notify\n");
- return gtk_selection_notify(widget, selection_event);
+ if (GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event) {
+ return GTK_WIDGET_CLASS(sciThis->parentClass)->selection_clear_event(widget, selection_event);
+ }
+ return TRUE;
}
-#endif
void ScintillaGTK::DragBegin(GtkWidget *, GdkDragContext *) {
//Platform::DebugPrintf("DragBegin\n");
@@ -2530,13 +2601,19 @@ gboolean ScintillaGTK::DragMotionThis(GdkDragContext *context,
try {
Point npt(x, y);
SetDragPosition(SPositionFromLocation(npt, false, false, UserVirtualSpace()));
+#if GTK_CHECK_VERSION(3,0,0)
+ GdkDragAction preferredAction = gdk_drag_context_get_suggested_action(context);
+ GdkDragAction actions = gdk_drag_context_get_actions(context);
+#else
GdkDragAction preferredAction = context->suggested_action;
+ GdkDragAction actions = context->actions;
+#endif
SelectionPosition pos = SPositionFromLocation(npt);
if ((inDragDrop == ddDragging) && (PositionInSelection(pos.Position()))) {
// Avoid dragging selection onto itself as that produces a move
// with no real effect but which creates undo actions.
preferredAction = static_cast<GdkDragAction>(0);
- } else if (context->actions == static_cast<GdkDragAction>
+ } else if (actions == static_cast<GdkDragAction>
(GDK_ACTION_COPY | GDK_ACTION_MOVE)) {
preferredAction = GDK_ACTION_MOVE;
}
@@ -2608,7 +2685,12 @@ void ScintillaGTK::DragDataGet(GtkWidget *widget, GdkDragContext *context,
if (!sciThis->sel.Empty()) {
sciThis->GetSelection(selection_data, info, &sciThis->drag);
}
- if (context->action == GDK_ACTION_MOVE) {
+#if GTK_CHECK_VERSION(3,0,0)
+ GdkDragAction action = gdk_drag_context_get_selected_action(context);
+#else
+ GdkDragAction action = context->action;
+#endif
+ if (action == GDK_ACTION_MOVE) {
for (size_t r=0; r<sciThis->sel.Count(); r++) {
if (sciThis->posDrop >= sciThis->sel.Range(r).Start()) {
if (sciThis->posDrop > sciThis->sel.Range(r).End()) {
@@ -2631,9 +2713,10 @@ int ScintillaGTK::TimeOut(ScintillaGTK *sciThis) {
return 1;
}
-int ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
- // Idler will be automatically stoped, if there is nothing
+gboolean ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
+ // Idler will be automatically stopped, if there is nothing
// to do while idle.
+ gdk_threads_enter();
bool ret = sciThis->Idle();
if (ret == false) {
// FIXME: This will remove the idler from GTK, we don't want to
@@ -2641,18 +2724,38 @@ int ScintillaGTK::IdleCallback(ScintillaGTK *sciThis) {
// returns false (although, it should be harmless).
sciThis->SetIdle(false);
}
+ gdk_threads_leave();
return ret;
}
-void ScintillaGTK::PopUpCB(ScintillaGTK *sciThis, guint action, GtkWidget *) {
+gboolean ScintillaGTK::StyleIdle(ScintillaGTK *sciThis) {
+ gdk_threads_enter();
+ sciThis->IdleStyling();
+ gdk_threads_leave();
+ // Idler will be automatically stopped
+ return FALSE;
+}
+
+void ScintillaGTK::QueueStyling(int upTo) {
+ Editor::QueueStyling(upTo);
+ if (!styleNeeded.active) {
+ // Only allow one style needed to be queued
+ styleNeeded.active = true;
+ g_idle_add_full(G_PRIORITY_HIGH_IDLE,
+ reinterpret_cast<GSourceFunc>(StyleIdle), this, NULL);
+ }
+}
+
+void ScintillaGTK::PopUpCB(GtkMenuItem *menuItem, ScintillaGTK *sciThis) {
+ guint action = (sptr_t)(g_object_get_data(G_OBJECT(menuItem), "CmdNum"));
if (action) {
sciThis->Command(action);
}
}
-gint ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis) {
+gboolean ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGTK *sciThis) {
try {
- if (event->window != widget->window)
+ if (event->window != WindowFromWidget(widget))
return FALSE;
if (event->type != GDK_BUTTON_PRESS)
return FALSE;
@@ -2663,18 +2766,35 @@ gint ScintillaGTK::PressCT(GtkWidget *widget, GdkEventButton *event, ScintillaGT
sciThis->CallTipClick();
} catch (...) {
}
-#if GTK_MAJOR_VERSION >= 2
return TRUE;
-#else
- return FALSE;
-#endif
}
-gint ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip *ctip) {
+#if GTK_CHECK_VERSION(3,0,0)
+
+gboolean ScintillaGTK::DrawCT(GtkWidget *widget, cairo_t *cr, CallTip *ctip) {
+ try {
+ Surface *surfaceWindow = Surface::Allocate();
+ if (surfaceWindow) {
+ surfaceWindow->Init(cr, widget);
+ surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ctip->codePage);
+ surfaceWindow->SetDBCSMode(ctip->codePage);
+ ctip->PaintCT(surfaceWindow);
+ surfaceWindow->Release();
+ delete surfaceWindow;
+ }
+ } catch (...) {
+ // No pointer back to Scintilla to save status
+ }
+ return TRUE;
+}
+
+#else
+
+gboolean ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip *ctip) {
try {
Surface *surfaceWindow = Surface::Allocate();
if (surfaceWindow) {
- surfaceWindow->Init(widget->window, widget);
+ surfaceWindow->Init(WindowFromWidget(widget), widget);
surfaceWindow->SetUnicodeMode(SC_CP_UTF8 == ctip->codePage);
surfaceWindow->SetDBCSMode(ctip->codePage);
ctip->PaintCT(surfaceWindow);
@@ -2687,6 +2807,8 @@ gint ScintillaGTK::ExposeCT(GtkWidget *widget, GdkEventExpose * /*ose*/, CallTip
return TRUE;
}
+#endif
+
sptr_t ScintillaGTK::DirectFunction(
ScintillaGTK *sciThis, unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
return sciThis->WndProc(iMessage, wParam, lParam);
@@ -2703,32 +2825,6 @@ static void scintilla_init(ScintillaObject *sci);
extern void Platform_Initialise();
extern void Platform_Finalise();
-#if GLIB_MAJOR_VERSION < 2
-GtkType scintilla_get_type() {
- static GtkType scintilla_type = 0;
- try {
-
- if (!scintilla_type) {
- Platform_Initialise();
- static GtkTypeInfo scintilla_info = {
- "Scintilla",
- sizeof (ScintillaObject),
- sizeof (ScintillaClass),
- (GtkClassInitFunc) scintilla_class_init,
- (GtkObjectInitFunc) scintilla_init,
- (gpointer) NULL,
- (gpointer) NULL,
- 0
- };
-
- scintilla_type = gtk_type_unique(gtk_container_get_type(), &scintilla_info);
- }
-
- } catch (...) {
- }
- return scintilla_type;
-}
-#else
GType scintilla_get_type() {
static GType scintilla_type = 0;
try {
@@ -2758,11 +2854,11 @@ GType scintilla_get_type() {
}
return scintilla_type;
}
-#endif
void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_class, GtkContainerClass *container_class) {
-#if GLIB_MAJOR_VERSION >= 2
Platform_Initialise();
+#ifdef SCI_LEXER
+ Scintilla_LinkLexers();
#endif
atomClipboard = gdk_atom_intern("CLIPBOARD", FALSE);
atomUTF8 = gdk_atom_intern("UTF8_STRING", FALSE);
@@ -2774,23 +2870,23 @@ void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_
// of the signal handlers here (those that currently attached to wDraw
// in Initialise() may require coordinate translation?)
-#if GLIB_MAJOR_VERSION < 2
- object_class->destroy = Destroy;
-#else
object_class->finalize = Destroy;
-#endif
+#if GTK_CHECK_VERSION(3,0,0)
+ widget_class->get_preferred_width = GetPreferredWidth;
+ widget_class->get_preferred_height = GetPreferredHeight;
+#else
widget_class->size_request = SizeRequest;
+#endif
widget_class->size_allocate = SizeAllocate;
+#if GTK_CHECK_VERSION(3,0,0)
+ widget_class->draw = DrawMain;
+#else
widget_class->expose_event = ExposeMain;
-#if GTK_MAJOR_VERSION < 2
- widget_class->draw = Draw;
#endif
widget_class->motion_notify_event = Motion;
widget_class->button_press_event = Press;
widget_class->button_release_event = MouseRelease;
-#if PLAT_GTK_WIN32 || (GTK_MAJOR_VERSION >= 2)
widget_class->scroll_event = ScrollEvent;
-#endif
widget_class->key_press_event = KeyPress;
widget_class->key_release_event = KeyRelease;
widget_class->focus_in_event = FocusIn;
@@ -2798,9 +2894,6 @@ void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_
widget_class->selection_received = SelectionReceived;
widget_class->selection_get = SelectionGet;
widget_class->selection_clear_event = SelectionClear;
-#if GTK_MAJOR_VERSION < 2
- widget_class->selection_notify_event = SelectionNotify;
-#endif
widget_class->drag_data_received = DragDataReceived;
widget_class->drag_motion = DragMotion;
@@ -2817,14 +2910,8 @@ void ScintillaGTK::ClassInit(OBJECT_CLASS* object_class, GtkWidgetClass *widget_
container_class->forall = MainForAll;
}
-#if GLIB_MAJOR_VERSION < 2
-#define GTK_CLASS_TYPE(c) (c->type)
-#define SIG_MARSHAL gtk_marshal_NONE__INT_POINTER
-#define MARSHAL_ARGUMENTS GTK_TYPE_INT, GTK_TYPE_POINTER
-#else
#define SIG_MARSHAL scintilla_marshal_NONE__INT_POINTER
#define MARSHAL_ARGUMENTS G_TYPE_INT, G_TYPE_POINTER
-#endif
static void scintilla_class_init(ScintillaClass *klass) {
try {
@@ -2832,29 +2919,6 @@ static void scintilla_class_init(ScintillaClass *klass) {
GtkWidgetClass *widget_class = (GtkWidgetClass*) klass;
GtkContainerClass *container_class = (GtkContainerClass*) klass;
-#if GLIB_MAJOR_VERSION < 2
- parent_class = (GtkWidgetClass*) gtk_type_class(gtk_container_get_type());
-
- scintilla_signals[COMMAND_SIGNAL] = gtk_signal_new(
- "command",
- GTK_RUN_LAST,
- GTK_CLASS_TYPE(object_class),
- GTK_SIGNAL_OFFSET(ScintillaClass, command),
- SIG_MARSHAL,
- GTK_TYPE_NONE,
- 2, MARSHAL_ARGUMENTS);
-
- scintilla_signals[NOTIFY_SIGNAL] = gtk_signal_new(
- SCINTILLA_NOTIFY,
- GTK_RUN_LAST,
- GTK_CLASS_TYPE(object_class),
- GTK_SIGNAL_OFFSET(ScintillaClass, notify),
- SIG_MARSHAL,
- GTK_TYPE_NONE,
- 2, MARSHAL_ARGUMENTS);
- gtk_object_class_add_signals(object_class,
- reinterpret_cast<unsigned int *>(scintilla_signals), LAST_SIGNAL);
-#else
GSignalFlags sigflags = GSignalFlags(G_SIGNAL_ACTION | G_SIGNAL_RUN_LAST);
scintilla_signals[COMMAND_SIGNAL] = g_signal_new(
"command",
@@ -2877,7 +2941,7 @@ static void scintilla_class_init(ScintillaClass *klass) {
SIG_MARSHAL,
G_TYPE_NONE,
2, MARSHAL_ARGUMENTS);
-#endif
+
klass->command = NULL;
klass->notify = NULL;
@@ -2888,18 +2952,18 @@ static void scintilla_class_init(ScintillaClass *klass) {
static void scintilla_init(ScintillaObject *sci) {
try {
+#if GTK_CHECK_VERSION(2,20,0)
+ gtk_widget_set_can_focus(GTK_WIDGET(sci), TRUE);
+#else
GTK_WIDGET_SET_FLAGS(sci, GTK_CAN_FOCUS);
+#endif
sci->pscin = new ScintillaGTK(sci);
} catch (...) {
}
}
GtkWidget* scintilla_new() {
-#if GLIB_MAJOR_VERSION < 2
- return GTK_WIDGET(gtk_type_new(scintilla_get_type()));
-#else
return GTK_WIDGET(g_object_new(scintilla_get_type(), NULL));
-#endif
}
void scintilla_set_id(ScintillaObject *sci, uptr_t id) {
diff --git a/plugins/scintilla/scintilla/Selection.cxx b/plugins/scintilla/scintilla/Selection.cxx
index 2cdbe60..305d721 100644
--- a/plugins/scintilla/scintilla/Selection.cxx
+++ b/plugins/scintilla/scintilla/Selection.cxx
@@ -20,6 +20,9 @@ using namespace Scintilla;
#endif
void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int length) {
+ if (position == startChange) {
+ virtualSpace = 0;
+ }
if (insertion) {
if (position > startChange) {
position += length;
@@ -31,6 +34,7 @@ void SelectionPosition::MoveForInsertDelete(bool insertion, int startChange, int
position -= length;
} else {
position = startChange;
+ virtualSpace = 0;
}
}
}
@@ -127,7 +131,7 @@ bool SelectionRange::Trim(SelectionRange range) {
} else if (start <= startRange) {
// Trim end
end = startRange;
- } else { //
+ } else { //
PLATFORM_ASSERT(end >= endRange);
// Trim start
start = endRange;
@@ -267,7 +271,7 @@ void Selection::TrimSelection(SelectionRange range) {
for (size_t i=0; i<ranges.size();) {
if ((i != mainRange) && (ranges[i].Trim(range))) {
// Trimmed to empty so remove
- for (size_t j=i;j<ranges.size()-1;j++) {
+ for (size_t j=i; j<ranges.size()-1; j++) {
ranges[j] = ranges[j+1];
if (j == mainRange-1)
mainRange--;
@@ -291,6 +295,11 @@ void Selection::AddSelection(SelectionRange range) {
mainRange = ranges.size() - 1;
}
+void Selection::AddSelectionWithoutTrim(SelectionRange range) {
+ ranges.push_back(range);
+ mainRange = ranges.size() - 1;
+}
+
void Selection::TentativeSelection(SelectionRange range) {
if (!tentativeMain) {
rangesSaved = ranges;
diff --git a/plugins/scintilla/scintilla/Selection.h b/plugins/scintilla/scintilla/Selection.h
index a3bac72..d7c7d79 100644
--- a/plugins/scintilla/scintilla/Selection.h
+++ b/plugins/scintilla/scintilla/Selection.h
@@ -57,10 +57,10 @@ public:
};
// Ordered range to make drawing simpler
-struct SelectionSegment {
+struct SelectionSegment {
SelectionPosition start;
SelectionPosition end;
- SelectionSegment() {
+ SelectionSegment() : start(), end() {
}
SelectionSegment(SelectionPosition a, SelectionPosition b) {
if (a < b) {
@@ -86,7 +86,7 @@ struct SelectionRange {
SelectionPosition caret;
SelectionPosition anchor;
- SelectionRange() {
+ SelectionRange() : caret(), anchor() {
}
SelectionRange(SelectionPosition single) : caret(single), anchor(single) {
}
@@ -148,7 +148,7 @@ public:
int MainAnchor() const;
SelectionRange &Rectangular();
SelectionSegment Limits() const;
- // This is for when you want to move the caret in response to a
+ // This is for when you want to move the caret in response to a
// user direction command - for rectangular selections, use the range
// that covers all selected text otherwise return the main selection.
SelectionSegment LimitsForRectangularElseMain() const;
@@ -166,6 +166,7 @@ public:
void TrimSelection(SelectionRange range);
void SetSelection(SelectionRange range);
void AddSelection(SelectionRange range);
+ void AddSelectionWithoutTrim(SelectionRange range);
void TentativeSelection(SelectionRange range);
void CommitTentative();
int CharacterInSelection(int posCharacter) const;
diff --git a/plugins/scintilla/scintilla/SparseState.h b/plugins/scintilla/scintilla/SparseState.h
new file mode 100644
index 0000000..655d742
--- /dev/null
+++ b/plugins/scintilla/scintilla/SparseState.h
@@ -0,0 +1,110 @@
+// Scintilla source code edit control
+/** @file SparseState.h
+ ** Hold lexer state that may change rarely.
+ ** This is often per-line state such as whether a particular type of section has been entered.
+ ** A state continues until it is changed.
+ **/
+// Copyright 2011 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef SPARSESTATE_H
+#define SPARSESTATE_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+template <typename T>
+class SparseState {
+ struct State {
+ int position;
+ T value;
+ State(int position_, T value_) : position(position_), value(value_) {
+ }
+ inline bool operator<(const State &other) const {
+ return position < other.position;
+ }
+ inline bool operator==(const State &other) const {
+ return (position == other.position) && (value == other.value);
+ }
+ };
+ int positionFirst;
+ typedef std::vector<State> stateVector;
+ stateVector states;
+
+ typename stateVector::iterator Find(int position) {
+ State searchValue(position, T());
+ return std::lower_bound(states.begin(), states.end(), searchValue);
+ }
+
+public:
+ SparseState(int positionFirst_=-1) {
+ positionFirst = positionFirst_;
+ }
+ void Set(int position, T value) {
+ Delete(position);
+ if (states.empty() || (value != states[states.size()-1].value)) {
+ states.push_back(State(position, value));
+ }
+ }
+ T ValueAt(int position) {
+ if (states.empty())
+ return T();
+ if (position < states[0].position)
+ return T();
+ typename stateVector::iterator low = Find(position);
+ if (low == states.end()) {
+ return states[states.size()-1].value;
+ } else {
+ if (low->position > position) {
+ --low;
+ }
+ return low->value;
+ }
+ }
+ bool Delete(int position) {
+ typename stateVector::iterator low = Find(position);
+ if (low != states.end()) {
+ states.erase(low, states.end());
+ return true;
+ }
+ return false;
+ }
+ size_t size() const {
+ return states.size();
+ }
+
+ // Returns true if Merge caused a significant change
+ bool Merge(const SparseState<T> &other, int ignoreAfter) {
+ // Changes caused beyond ignoreAfter are not significant
+ Delete(ignoreAfter+1);
+
+ bool different = true;
+ bool changed = false;
+ typename stateVector::iterator low = Find(other.positionFirst);
+ if (static_cast<size_t>(states.end() - low) == other.states.size()) {
+ // Same number in other as after positionFirst in this
+ different = !std::equal(low, states.end(), other.states.begin());
+ }
+ if (different) {
+ if (low != states.end()) {
+ states.erase(low, states.end());
+ changed = true;
+ }
+ typename stateVector::const_iterator startOther = other.states.begin();
+ if (!states.empty() && states.back().value == startOther->value)
+ ++startOther;
+ if (startOther != other.states.end()) {
+ states.insert(states.end(), startOther, other.states.end());
+ changed = true;
+ }
+ }
+ return changed;
+ }
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/SplitVector.h b/plugins/scintilla/scintilla/SplitVector.h
index af4e890..44d5ddc 100644
--- a/plugins/scintilla/scintilla/SplitVector.h
+++ b/plugins/scintilla/scintilla/SplitVector.h
@@ -1,6 +1,6 @@
// Scintilla source code edit control
/** @file SplitVector.h
- ** Main data structure for holding arrays that handle insertions
+ ** Main data structure for holding arrays that handle insertions
** and deletions efficiently.
**/
// Copyright 1998-2007 by Neil Hodgson <neilh scintilla org>
@@ -97,7 +97,7 @@ public:
/// Retrieve the character at a particular position.
/// Retrieving positions outside the range of the buffer returns 0.
- /// The assertions here are disabled since calling code can be
+ /// The assertions here are disabled since calling code can be
/// simpler if out of range access works and returns 0.
T ValueAt(int position) const {
if (position < part1Length) {
@@ -135,7 +135,7 @@ public:
}
}
- T& operator[](int position) const {
+ T &operator[](int position) const {
PLATFORM_ASSERT(position >= 0 && position < lengthBody);
if (position < part1Length) {
return body[position];
@@ -182,14 +182,14 @@ public:
}
}
- /// Ensure at least length elements allocated,
+ /// Ensure at least length elements allocated,
/// appending zero valued elements if needed.
void EnsureLength(int wantedLength) {
if (Length() < wantedLength) {
InsertValue(Length(), wantedLength - Length(), 0);
}
}
-
+
/// Insert text into the buffer from an array.
void InsertFromArray(int positionToInsert, const T s[], int positionFrom, int insertLength) {
PLATFORM_ASSERT((positionToInsert >= 0) && (positionToInsert <= lengthBody));
@@ -238,7 +238,24 @@ public:
DeleteRange(0, lengthBody);
}
- T* BufferPointer() {
+ // Retrieve a range of elements into an array
+ void GetRange(T *buffer, int position, int retrieveLength) const {
+ // Split into up to 2 ranges, before and after the split then use memcpy on each.
+ int range1Length = 0;
+ if (position < part1Length) {
+ int part1AfterPosition = part1Length - position;
+ range1Length = retrieveLength;
+ if (range1Length > part1AfterPosition)
+ range1Length = part1AfterPosition;
+ }
+ memcpy(buffer, body + position, range1Length * sizeof(T));
+ buffer += range1Length;
+ position = position + range1Length + gapLength;
+ int range2Length = retrieveLength - range1Length;
+ memcpy(buffer, body + position, range2Length * sizeof(T));
+ }
+
+ T *BufferPointer() {
RoomFor(1);
GapTo(lengthBody);
body[lengthBody] = 0;
diff --git a/plugins/scintilla/scintilla/Style.cxx b/plugins/scintilla/scintilla/Style.cxx
index 4314dec..25efcd6 100644
--- a/plugins/scintilla/scintilla/Style.cxx
+++ b/plugins/scintilla/scintilla/Style.cxx
@@ -16,8 +16,45 @@
using namespace Scintilla;
#endif
+FontAlias::FontAlias() {
+}
+
+FontAlias::~FontAlias() {
+ SetID(0);
+ // ~Font will not release the actual font resource sine it is now 0
+}
+
+void FontAlias::MakeAlias(Font &fontOrigin) {
+ SetID(fontOrigin.GetID());
+}
+
+void FontAlias::ClearFont() {
+ SetID(0);
+}
+
+bool FontSpecification::EqualTo(const FontSpecification &other) const {
+ return bold == other.bold &&
+ italic == other.italic &&
+ size == other.size &&
+ characterSet == other.characterSet &&
+ fontName == other.fontName;
+}
+
+FontMeasurements::FontMeasurements() {
+ Clear();
+}
+
+void FontMeasurements::Clear() {
+ lineHeight = 2;
+ ascent = 1;
+ descent = 1;
+ externalLeading = 0;
+ aveCharWidth = 1;
+ spaceWidth = 1;
+ sizeZoomed = 2;
+}
+
Style::Style() {
- aliasOfDefaultFont = true;
Clear(ColourDesired(0, 0, 0), ColourDesired(0xff, 0xff, 0xff),
Platform::DefaultFontSize(), 0, SC_CHARSET_DEFAULT,
false, false, false, false, caseMixed, true, true, false);
@@ -42,11 +79,6 @@ Style::Style(const Style &source) {
}
Style::~Style() {
- if (aliasOfDefaultFont)
- font.SetID(0);
- else
- font.Release();
- aliasOfDefaultFont = false;
}
Style &Style::operator=(const Style &source) {
@@ -70,10 +102,10 @@ Style &Style::operator=(const Style &source) {
}
void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
- const char *fontName_, int characterSet_,
- bool bold_, bool italic_, bool eolFilled_,
- bool underline_, ecaseForced caseForce_,
- bool visible_, bool changeable_, bool hotspot_) {
+ const char *fontName_, int characterSet_,
+ bool bold_, bool italic_, bool eolFilled_,
+ bool underline_, ecaseForced caseForce_,
+ bool visible_, bool changeable_, bool hotspot_) {
fore.desired = fore_;
back.desired = back_;
characterSet = characterSet_;
@@ -87,72 +119,31 @@ void Style::Clear(ColourDesired fore_, ColourDesired back_, int size_,
visible = visible_;
changeable = changeable_;
hotspot = hotspot_;
- if (aliasOfDefaultFont)
- font.SetID(0);
- else
- font.Release();
- aliasOfDefaultFont = false;
+ font.ClearFont();
+ FontMeasurements::Clear();
}
void Style::ClearTo(const Style &source) {
Clear(
- source.fore.desired,
- source.back.desired,
- source.size,
- source.fontName,
- source.characterSet,
- source.bold,
- source.italic,
- source.eolFilled,
- source.underline,
- source.caseForce,
- source.visible,
- source.changeable,
- source.hotspot);
+ source.fore.desired,
+ source.back.desired,
+ source.size,
+ source.fontName,
+ source.characterSet,
+ source.bold,
+ source.italic,
+ source.eolFilled,
+ source.underline,
+ source.caseForce,
+ source.visible,
+ source.changeable,
+ source.hotspot);
}
-bool Style::EquivalentFontTo(const Style *other) const {
- if (bold != other->bold ||
- italic != other->italic ||
- size != other->size ||
- characterSet != other->characterSet)
- return false;
- if (fontName == other->fontName)
- return true;
- if (!fontName)
- return false;
- if (!other->fontName)
- return false;
- return strcmp(fontName, other->fontName) == 0;
-}
-
-void Style::Realise(Surface &surface, int zoomLevel, Style *defaultStyle, int extraFontFlag) {
- sizeZoomed = size + zoomLevel;
- if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
- sizeZoomed = 2;
-
- if (aliasOfDefaultFont)
- font.SetID(0);
- else
- font.Release();
- int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
- aliasOfDefaultFont = defaultStyle &&
- (EquivalentFontTo(defaultStyle) || !fontName);
- if (aliasOfDefaultFont) {
- font.SetID(defaultStyle->font.GetID());
- } else if (fontName) {
- font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
- } else {
- font.SetID(0);
- }
-
+void Style::Copy(Font &font_, const FontMeasurements &fm_) {
+ font.MakeAlias(font_);
+ (FontMeasurements &)(*this) = fm_;
+#if PLAT_WX
ascent = surface.Ascent(font);
- descent = surface.Descent(font);
- // Probably more typographically correct to include leading
- // but that means more complex drawing as leading must be erased
- //lineHeight = surface.ExternalLeading() + surface.Height();
- externalLeading = surface.ExternalLeading(font);
- lineHeight = surface.Height(font);
- aveCharWidth = surface.AverageCharWidth(font);
- spaceWidth = surface.WidthChar(font, ' ');
+#endif
}
diff --git a/plugins/scintilla/scintilla/Style.h b/plugins/scintilla/scintilla/Style.h
index 0be3d4f..29122b0 100644
--- a/plugins/scintilla/scintilla/Style.h
+++ b/plugins/scintilla/scintilla/Style.h
@@ -12,18 +12,54 @@
namespace Scintilla {
#endif
+struct FontSpecification {
+ const char *fontName;
+ bool bold;
+ bool italic;
+ int size;
+ int characterSet;
+ int extraFontFlag;
+ FontSpecification() :
+ fontName(0),
+ bold(false),
+ italic(false),
+ size(10),
+ characterSet(0),
+ extraFontFlag(0) {
+ }
+ bool EqualTo(const FontSpecification &other) const;
+};
+
+// Just like Font but only has a copy of the FontID so should not delete it
+class FontAlias : public Font {
+ // Private so FontAlias objects can not be copied
+ FontAlias(const FontAlias &);
+ FontAlias &operator=(const FontAlias &);
+public:
+ FontAlias();
+ virtual ~FontAlias();
+ void MakeAlias(Font &fontOrigin);
+ void ClearFont();
+};
+
+struct FontMeasurements {
+ unsigned int lineHeight;
+ unsigned int ascent;
+ unsigned int descent;
+ unsigned int externalLeading;
+ unsigned int aveCharWidth;
+ unsigned int spaceWidth;
+ int sizeZoomed;
+ FontMeasurements();
+ void Clear();
+};
+
/**
*/
-class Style {
+class Style : public FontSpecification, public FontMeasurements {
public:
ColourPair fore;
ColourPair back;
- bool aliasOfDefaultFont;
- bool bold;
- bool italic;
- int size;
- const char *fontName;
- int characterSet;
bool eolFilled;
bool underline;
enum ecaseForced {caseMixed, caseUpper, caseLower};
@@ -32,14 +68,7 @@ public:
bool changeable;
bool hotspot;
- Font font;
- int sizeZoomed;
- unsigned int lineHeight;
- unsigned int ascent;
- unsigned int descent;
- unsigned int externalLeading;
- unsigned int aveCharWidth;
- unsigned int spaceWidth;
+ FontAlias font;
Style();
Style(const Style &source);
@@ -52,9 +81,8 @@ public:
bool underline_, ecaseForced caseForce_,
bool visible_, bool changeable_, bool hotspot_);
void ClearTo(const Style &source);
- bool EquivalentFontTo(const Style *other) const;
- void Realise(Surface &surface, int zoomLevel, Style *defaultStyle = 0, int extraFontFlag = 0);
- bool IsProtected() const { return !(changeable && visible);};
+ void Copy(Font &font_, const FontMeasurements &fm_);
+ bool IsProtected() const { return !(changeable && visible);}
};
#ifdef SCI_NAMESPACE
diff --git a/plugins/scintilla/scintilla/StyleContext.cxx b/plugins/scintilla/scintilla/StyleContext.cxx
old mode 100755
new mode 100644
index 4a1f716..cf59fdd
--- a/plugins/scintilla/scintilla/StyleContext.cxx
+++ b/plugins/scintilla/scintilla/StyleContext.cxx
@@ -9,10 +9,11 @@
#include <string.h>
#include <ctype.h>
#include <stdio.h>
+#include <assert.h>
-#include "Platform.h"
+#include "ILexer.h"
-#include "PropSet.h"
+#include "LexAccessor.h"
#include "Accessor.h"
#include "StyleContext.h"
@@ -22,7 +23,7 @@ using namespace Scintilla;
static void getRange(unsigned int start,
unsigned int end,
- Accessor &styler,
+ LexAccessor &styler,
char *s,
unsigned int len) {
unsigned int i = 0;
@@ -39,7 +40,7 @@ void StyleContext::GetCurrent(char *s, unsigned int len) {
static void getRangeLowered(unsigned int start,
unsigned int end,
- Accessor &styler,
+ LexAccessor &styler,
char *s,
unsigned int len) {
unsigned int i = 0;
diff --git a/plugins/scintilla/scintilla/StyleContext.h b/plugins/scintilla/scintilla/StyleContext.h
old mode 100755
new mode 100644
index 9342ebd..15d216b
--- a/plugins/scintilla/scintilla/StyleContext.h
+++ b/plugins/scintilla/scintilla/StyleContext.h
@@ -5,18 +5,28 @@
// Copyright 1998-2004 by Neil Hodgson <neilh scintilla org>
// This file is in the public domain.
+#ifndef STYLECONTEXT_H
+#define STYLECONTEXT_H
+
#ifdef SCI_NAMESPACE
namespace Scintilla {
#endif
+static inline int MakeLowerCase(int ch) {
+ if (ch < 'A' || ch > 'Z')
+ return ch;
+ else
+ return ch - 'A' + 'a';
+}
+
// 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
// syntactically significant. UTF-8 avoids this as all trail bytes are >= 0x80
class StyleContext {
- Accessor &styler;
+ LexAccessor &styler;
unsigned int endPos;
- StyleContext& operator=(const StyleContext&);
+ 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))) {
@@ -41,7 +51,7 @@ public:
int chNext;
StyleContext(unsigned int startPos, unsigned int length,
- int initStyle, Accessor &styler_, char chMask=31) :
+ int initStyle, LexAccessor &styler_, char chMask=31) :
styler(styler_),
endPos(startPos + length),
currentPos(startPos),
@@ -64,8 +74,9 @@ public:
}
void Complete() {
styler.ColourTo(currentPos - 1, state);
+ styler.Flush();
}
- bool More() {
+ bool More() const {
return currentPos < endPos;
}
void Forward() {
@@ -108,10 +119,10 @@ public:
int GetRelative(int n) {
return static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n));
}
- bool Match(char ch0) {
+ bool Match(char ch0) const {
return ch == static_cast<unsigned char>(ch0);
}
- bool Match(char ch0, char ch1) {
+ bool Match(char ch0, char ch1) const {
return (ch == static_cast<unsigned char>(ch0)) && (chNext == static_cast<unsigned char>(ch1));
}
bool Match(const char *s) {
@@ -131,15 +142,15 @@ public:
return true;
}
bool MatchIgnoreCase(const char *s) {
- if (tolower(ch) != static_cast<unsigned char>(*s))
+ if (MakeLowerCase(ch) != static_cast<unsigned char>(*s))
return false;
s++;
- if (tolower(chNext) != static_cast<unsigned char>(*s))
+ if (MakeLowerCase(chNext) != static_cast<unsigned char>(*s))
return false;
s++;
for (int n=2; *s; n++) {
if (static_cast<unsigned char>(*s) !=
- tolower(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
+ MakeLowerCase(static_cast<unsigned char>(styler.SafeGetCharAt(currentPos+n))))
return false;
s++;
}
@@ -154,24 +165,4 @@ public:
}
#endif
-inline bool IsASpace(unsigned int ch) {
- return (ch == ' ') || ((ch >= 0x09) && (ch <= 0x0d));
-}
-
-inline bool IsASpaceOrTab(unsigned int ch) {
- return (ch == ' ') || (ch == '\t');
-}
-
-inline bool IsADigit(unsigned int ch) {
- return (ch >= '0') && (ch <= '9');
-}
-
-inline bool IsADigit(unsigned int ch, unsigned int base) {
- if (base <= 10) {
- return (ch >= '0') && (ch < '0' + base);
- } else {
- return ((ch >= '0') && (ch <= '9')) ||
- ((ch >= 'A') && (ch < 'A' + base - 10)) ||
- ((ch >= 'a') && (ch < 'a' + base - 10));
- }
-}
+#endif
diff --git a/plugins/scintilla/scintilla/UniConversion.cxx b/plugins/scintilla/scintilla/UniConversion.cxx
index 7dbe9e2..2ef7584 100644
--- a/plugins/scintilla/scintilla/UniConversion.cxx
+++ b/plugins/scintilla/scintilla/UniConversion.cxx
@@ -1,6 +1,6 @@
// Scintilla source code edit control
/** @file UniConversion.cxx
- ** Functions to handle UFT-8 and UCS-2 strings.
+ ** Functions to handle UTF-8 and UTF-16 strings.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
@@ -61,10 +61,22 @@ void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned
putf[len] = '\0';
}
+unsigned int UTF8CharLength(unsigned char ch) {
+ if (ch < 0x80) {
+ return 1;
+ } else if (ch < 0x80 + 0x40 + 0x20) {
+ return 2;
+ } else if (ch < 0x80 + 0x40 + 0x20 + 0x10) {
+ return 3;
+ } else {
+ return 4;
+ }
+}
+
unsigned int UTF16Length(const char *s, unsigned int len) {
unsigned int ulen = 0;
unsigned int charLen;
- for (unsigned int i=0;i<len;) {
+ for (unsigned int i=0; i<len;) {
unsigned char ch = static_cast<unsigned char>(s[i]);
if (ch < 0x80) {
charLen = 1;
diff --git a/plugins/scintilla/scintilla/UniConversion.h b/plugins/scintilla/scintilla/UniConversion.h
index fd420a6..2de2ef3 100644
--- a/plugins/scintilla/scintilla/UniConversion.h
+++ b/plugins/scintilla/scintilla/UniConversion.h
@@ -1,12 +1,13 @@
// Scintilla source code edit control
/** @file UniConversion.h
- ** Functions to handle UFT-8 and UCS-2 strings.
+ ** Functions to handle UTF-8 and UTF-16 strings.
**/
// Copyright 1998-2001 by Neil Hodgson <neilh scintilla org>
// The License.txt file describes the conditions under which this software may be distributed.
unsigned int UTF8Length(const wchar_t *uptr, unsigned int tlen);
void UTF8FromUTF16(const wchar_t *uptr, unsigned int tlen, char *putf, unsigned int len);
+unsigned int UTF8CharLength(unsigned char ch);
unsigned int UTF16Length(const char *s, unsigned int len);
unsigned int UTF16FromUTF8(const char *s, unsigned int len, wchar_t *tbuf, unsigned int tlen);
diff --git a/plugins/scintilla/scintilla/ViewStyle.cxx b/plugins/scintilla/scintilla/ViewStyle.cxx
index 8e9c4a4..58e0ede 100644
--- a/plugins/scintilla/scintilla/ViewStyle.cxx
+++ b/plugins/scintilla/scintilla/ViewStyle.cxx
@@ -24,7 +24,7 @@ using namespace Scintilla;
#endif
MarginStyle::MarginStyle() :
- style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false) {
+ style(SC_MARGIN_SYMBOL), width(0), mask(0), sensitive(false), cursor(SC_CURSORREVERSEARROW) {
}
// A list of the fontnames - avoids wasting space in each style
@@ -41,7 +41,7 @@ FontNames::~FontNames() {
}
void FontNames::Clear() {
- for (int i=0;i<max;i++) {
+ for (int i=0; i<max; i++) {
delete []names[i];
}
max = 0;
@@ -50,7 +50,7 @@ void FontNames::Clear() {
const char *FontNames::Save(const char *name) {
if (!name)
return 0;
- for (int i=0;i<max;i++) {
+ for (int i=0; i<max; i++) {
if (strcmp(names[i], name) == 0) {
return names[i];
}
@@ -59,7 +59,7 @@ const char *FontNames::Save(const char *name) {
// Grow array
int sizeNew = size * 2;
char **namesNew = new char *[sizeNew];
- for (int j=0;j<max;j++) {
+ for (int j=0; j<max; j++) {
namesNew[j] = names[j];
}
delete []names;
@@ -72,21 +72,75 @@ const char *FontNames::Save(const char *name) {
return names[max-1];
}
+FontRealised::FontRealised(const FontSpecification &fs) {
+ frNext = NULL;
+ (FontSpecification &)(*this) = fs;
+}
+
+FontRealised::~FontRealised() {
+ delete frNext;
+ frNext = 0;
+}
+
+void FontRealised::Realise(Surface &surface, int zoomLevel) {
+ PLATFORM_ASSERT(fontName);
+ sizeZoomed = size + zoomLevel;
+ if (sizeZoomed <= 2) // Hangs if sizeZoomed <= 1
+ sizeZoomed = 2;
+
+ int deviceHeight = surface.DeviceHeightFont(sizeZoomed);
+ font.Create(fontName, characterSet, deviceHeight, bold, italic, extraFontFlag);
+
+ ascent = surface.Ascent(font);
+ descent = surface.Descent(font);
+ externalLeading = surface.ExternalLeading(font);
+ lineHeight = surface.Height(font);
+ aveCharWidth = surface.AverageCharWidth(font);
+ spaceWidth = surface.WidthChar(font, ' ');
+ if (frNext) {
+ frNext->Realise(surface, zoomLevel);
+ }
+}
+
+FontRealised *FontRealised::Find(const FontSpecification &fs) {
+ if (!fs.fontName)
+ return this;
+ FontRealised *fr = this;
+ while (fr) {
+ if (fr->EqualTo(fs))
+ return fr;
+ fr = fr->frNext;
+ }
+ return 0;
+}
+
+void FontRealised::FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent) {
+ FontRealised *fr = this;
+ while (fr) {
+ if (maxAscent < fr->ascent)
+ maxAscent = fr->ascent;
+ if (maxDescent < fr->descent)
+ maxDescent = fr->descent;
+ fr = fr->frNext;
+ }
+}
+
ViewStyle::ViewStyle() {
Init();
}
ViewStyle::ViewStyle(const ViewStyle &source) {
+ frFirst = NULL;
Init(source.stylesSize);
- for (unsigned int sty=0;sty<source.stylesSize;sty++) {
+ for (unsigned int sty=0; sty<source.stylesSize; sty++) {
styles[sty] = source.styles[sty];
// Can't just copy fontname as its lifetime is relative to its owning ViewStyle
styles[sty].fontName = fontNames.Save(source.styles[sty].fontName);
}
- for (int mrk=0;mrk<=MARKER_MAX;mrk++) {
+ for (int mrk=0; mrk<=MARKER_MAX; mrk++) {
markers[mrk] = source.markers[mrk];
}
- for (int ind=0;ind<=INDIC_MAX;ind++) {
+ for (int ind=0; ind<=INDIC_MAX; ind++) {
indicators[ind] = source.indicators[ind];
}
@@ -129,9 +183,10 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
caretStyle = source.caretStyle;
caretWidth = source.caretWidth;
someStylesProtected = false;
+ someStylesForceCase = false;
leftMarginWidth = source.leftMarginWidth;
rightMarginWidth = source.rightMarginWidth;
- for (int i=0;i < margins; i++) {
+ for (int i=0; i < margins; i++) {
ms[i] = source.ms[i];
}
symbolMargin = source.symbolMargin;
@@ -149,14 +204,21 @@ ViewStyle::ViewStyle(const ViewStyle &source) {
marginStyleOffset = source.marginStyleOffset;
annotationVisible = source.annotationVisible;
annotationStyleOffset = source.annotationStyleOffset;
+ braceHighlightIndicatorSet = source.braceHighlightIndicatorSet;
+ braceHighlightIndicator = source.braceHighlightIndicator;
+ braceBadLightIndicatorSet = source.braceBadLightIndicatorSet;
+ braceBadLightIndicator = source.braceBadLightIndicator;
}
ViewStyle::~ViewStyle() {
delete []styles;
styles = NULL;
+ delete frFirst;
+ frFirst = NULL;
}
void ViewStyle::Init(size_t stylesSize_) {
+ frFirst = NULL;
stylesSize = 0;
styles = NULL;
AllocStyles(stylesSize_);
@@ -213,6 +275,7 @@ void ViewStyle::Init(size_t stylesSize_) {
caretStyle = CARETSTYLE_LINE;
caretWidth = 1;
someStylesProtected = false;
+ someStylesForceCase = false;
hotspotForegroundSet = false;
hotspotForeground.desired = ColourDesired(0, 0, 0xff);
@@ -253,18 +316,22 @@ void ViewStyle::Init(size_t stylesSize_) {
marginStyleOffset = 0;
annotationVisible = ANNOTATION_HIDDEN;
annotationStyleOffset = 0;
+ braceHighlightIndicatorSet = false;
+ braceHighlightIndicator = 0;
+ braceBadLightIndicatorSet = false;
+ braceBadLightIndicator = 0;
}
void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
unsigned int i;
- for (i=0;i<stylesSize;i++) {
+ for (i=0; i<stylesSize; i++) {
pal.WantFind(styles[i].fore, want);
pal.WantFind(styles[i].back, want);
}
- for (i=0;i<(sizeof(indicators)/sizeof(indicators[0]));i++) {
+ for (i=0; i<(sizeof(indicators)/sizeof(indicators[0])); i++) {
pal.WantFind(indicators[i].fore, want);
}
- for (i=0;i<(sizeof(markers)/sizeof(markers[0]));i++) {
+ for (i=0; i<(sizeof(markers)/sizeof(markers[0])); i++) {
markers[i].RefreshColourPalette(pal, want);
}
pal.WantFind(selforeground, want);
@@ -288,29 +355,59 @@ void ViewStyle::RefreshColourPalette(Palette &pal, bool want) {
pal.WantFind(hotspotBackground, want);
}
+void ViewStyle::CreateFont(const FontSpecification &fs) {
+ if (fs.fontName) {
+ for (FontRealised *cur=frFirst; cur; cur=cur->frNext) {
+ if (cur->EqualTo(fs))
+ return;
+ if (!cur->frNext) {
+ cur->frNext = new FontRealised(fs);
+ return;
+ }
+ }
+ frFirst = new FontRealised(fs);
+ }
+}
+
void ViewStyle::Refresh(Surface &surface) {
+ delete frFirst;
+ frFirst = NULL;
selbar.desired = Platform::Chrome();
selbarlight.desired = Platform::ChromeHighlight();
- styles[STYLE_DEFAULT].Realise(surface, zoomLevel, NULL, extraFontFlag);
- maxAscent = styles[STYLE_DEFAULT].ascent;
- maxDescent = styles[STYLE_DEFAULT].descent;
- someStylesProtected = false;
+
for (unsigned int i=0; i<stylesSize; i++) {
- if (i != STYLE_DEFAULT) {
- styles[i].Realise(surface, zoomLevel, &styles[STYLE_DEFAULT], extraFontFlag);
- if (maxAscent < styles[i].ascent)
- maxAscent = styles[i].ascent;
- if (maxDescent < styles[i].descent)
- maxDescent = styles[i].descent;
- }
- if (styles[i].IsProtected()) {
- someStylesProtected = true;
- }
+ styles[i].extraFontFlag = extraFontFlag;
+ }
+
+ CreateFont(styles[STYLE_DEFAULT]);
+ for (unsigned int j=0; j<stylesSize; j++) {
+ CreateFont(styles[j]);
}
+
+ frFirst->Realise(surface, zoomLevel);
+
+ for (unsigned int k=0; k<stylesSize; k++) {
+ FontRealised *fr = frFirst->Find(styles[k]);
+ styles[k].Copy(fr->font, *fr);
+ }
+ maxAscent = 1;
+ maxDescent = 1;
+ frFirst->FindMaxAscentDescent(maxAscent, maxDescent);
maxAscent += extraAscent;
maxDescent += extraDescent;
-
lineHeight = maxAscent + maxDescent;
+
+ someStylesProtected = false;
+ someStylesForceCase = false;
+ for (unsigned int l=0; l<stylesSize; l++) {
+ if (styles[l].IsProtected()) {
+ someStylesProtected = true;
+ }
+ if (styles[l].caseForce != Style::caseMixed) {
+ someStylesForceCase = true;
+ }
+ }
+
aveCharWidth = styles[STYLE_DEFAULT].aveCharWidth;
spaceWidth = styles[STYLE_DEFAULT].spaceWidth;
@@ -355,10 +452,10 @@ void ViewStyle::EnsureStyle(size_t index) {
void ViewStyle::ResetDefaultStyle() {
styles[STYLE_DEFAULT].Clear(ColourDesired(0,0,0),
- ColourDesired(0xff,0xff,0xff),
- Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
- SC_CHARSET_DEFAULT,
- false, false, false, false, Style::caseMixed, true, true, false);
+ ColourDesired(0xff,0xff,0xff),
+ Platform::DefaultFontSize(), fontNames.Save(Platform::DefaultFont()),
+ SC_CHARSET_DEFAULT,
+ false, false, false, false, Style::caseMixed, true, true, false);
}
void ViewStyle::ClearStyles() {
diff --git a/plugins/scintilla/scintilla/ViewStyle.h b/plugins/scintilla/scintilla/ViewStyle.h
index 22e365b..b038a9b 100644
--- a/plugins/scintilla/scintilla/ViewStyle.h
+++ b/plugins/scintilla/scintilla/ViewStyle.h
@@ -20,6 +20,7 @@ public:
int width;
int mask;
bool sensitive;
+ int cursor;
MarginStyle();
};
@@ -38,6 +39,20 @@ public:
const char *Save(const char *name);
};
+class FontRealised : public FontSpecification, public FontMeasurements {
+ // Private so FontRealised objects can not be copied
+ FontRealised(const FontRealised &);
+ FontRealised &operator=(const FontRealised &);
+public:
+ Font font;
+ FontRealised *frNext;
+ FontRealised(const FontSpecification &fs);
+ virtual ~FontRealised();
+ void Realise(Surface &surface, int zoomLevel);
+ FontRealised *Find(const FontSpecification &fs);
+ void FindMaxAscentDescent(unsigned int &maxAscent, unsigned int &maxDescent);
+};
+
enum IndentView {ivNone, ivReal, ivLookForward, ivLookBoth};
enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterIndent=2};
@@ -47,6 +62,7 @@ enum WhiteSpaceVisibility {wsInvisible=0, wsVisibleAlways=1, wsVisibleAfterInden
class ViewStyle {
public:
FontNames fontNames;
+ FontRealised *frFirst;
size_t stylesSize;
Style *styles;
LineMarker markers[MARKER_MAX + 1];
@@ -106,17 +122,23 @@ public:
int caretStyle;
int caretWidth;
bool someStylesProtected;
+ bool someStylesForceCase;
int extraFontFlag;
int extraAscent;
int extraDescent;
int marginStyleOffset;
int annotationVisible;
int annotationStyleOffset;
+ bool braceHighlightIndicatorSet;
+ int braceHighlightIndicator;
+ bool braceBadLightIndicatorSet;
+ int braceBadLightIndicator;
ViewStyle();
ViewStyle(const ViewStyle &source);
~ViewStyle();
void Init(size_t stylesSize_=64);
+ void CreateFont(const FontSpecification &fs);
void RefreshColourPalette(Palette &pal, bool want);
void Refresh(Surface &surface);
void AllocStyles(size_t sizeNew);
diff --git a/plugins/scintilla/scintilla/WordList.cxx b/plugins/scintilla/scintilla/WordList.cxx
new file mode 100644
index 0000000..cda35ec
--- /dev/null
+++ b/plugins/scintilla/scintilla/WordList.cxx
@@ -0,0 +1,205 @@
+// Scintilla source code edit control
+/** @file KeyWords.cxx
+ ** Colourise for particular languages.
+ **/
+// Copyright 1998-2002 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+#include "WordList.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+/**
+ * Creates an array that points into each word in the string and puts \0 terminators
+ * after each word.
+ */
+static char **ArrayFromWordList(char *wordlist, int *len, bool onlyLineEnds = false) {
+ int prev = '\n';
+ int words = 0;
+ // For rapid determination of whether a character is a separator, build
+ // a look up table.
+ bool wordSeparator[256];
+ for (int i=0; i<256; i++) {
+ wordSeparator[i] = false;
+ }
+ wordSeparator['\r'] = true;
+ wordSeparator['\n'] = true;
+ if (!onlyLineEnds) {
+ wordSeparator[' '] = true;
+ wordSeparator['\t'] = true;
+ }
+ for (int j = 0; wordlist[j]; j++) {
+ int curr = static_cast<unsigned char>(wordlist[j]);
+ if (!wordSeparator[curr] && wordSeparator[prev])
+ words++;
+ prev = curr;
+ }
+ char **keywords = new char *[words + 1];
+ if (keywords) {
+ words = 0;
+ prev = '\0';
+ size_t slen = strlen(wordlist);
+ for (size_t k = 0; k < slen; k++) {
+ if (!wordSeparator[static_cast<unsigned char>(wordlist[k])]) {
+ if (!prev) {
+ keywords[words] = &wordlist[k];
+ words++;
+ }
+ } else {
+ wordlist[k] = '\0';
+ }
+ prev = wordlist[k];
+ }
+ keywords[words] = &wordlist[slen];
+ *len = words;
+ } else {
+ *len = 0;
+ }
+ return keywords;
+}
+
+bool WordList::operator!=(const WordList &other) const {
+ if (len != other.len)
+ return true;
+ for (int i=0; i<len; i++) {
+ if (strcmp(words[i], other.words[i]) != 0)
+ return true;
+ }
+ return false;
+}
+
+void WordList::Clear() {
+ if (words) {
+ delete []list;
+ delete []words;
+ }
+ words = 0;
+ list = 0;
+ len = 0;
+}
+
+extern "C" int cmpString(const void *a1, const void *a2) {
+ // Can't work out the correct incantation to use modern casts here
+ return strcmp(*(char **)(a1), *(char **)(a2));
+}
+
+static void SortWordList(char **words, unsigned int len) {
+ qsort(reinterpret_cast<void *>(words), len, sizeof(*words),
+ cmpString);
+}
+
+void WordList::Set(const char *s) {
+ Clear();
+ list = new char[strlen(s) + 1];
+ strcpy(list, s);
+ words = ArrayFromWordList(list, &len, onlyLineEnds);
+ SortWordList(words, len);
+ for (unsigned int k = 0; k < (sizeof(starts) / sizeof(starts[0])); k++)
+ starts[k] = -1;
+ for (int l = len - 1; l >= 0; l--) {
+ unsigned char indexChar = words[l][0];
+ starts[indexChar] = l;
+ }
+}
+
+/** Check whether a string is in the list.
+ * List elements are either exact matches or prefixes.
+ * Prefix elements start with '^' and match all strings that start with the rest of the element
+ * so '^GTK_' matches 'GTK_X', 'GTK_MAJOR_VERSION', and 'GTK_'.
+ */
+bool WordList::InList(const char *s) const {
+ if (0 == words)
+ return false;
+ unsigned char firstChar = s[0];
+ int j = starts[firstChar];
+ if (j >= 0) {
+ while ((unsigned char)words[j][0] == firstChar) {
+ if (s[1] == words[j][1]) {
+ const char *a = words[j] + 1;
+ const char *b = s + 1;
+ while (*a && *a == *b) {
+ a++;
+ b++;
+ }
+ if (!*a && !*b)
+ return true;
+ }
+ j++;
+ }
+ }
+ j = starts['^'];
+ if (j >= 0) {
+ while (words[j][0] == '^') {
+ const char *a = words[j] + 1;
+ const char *b = s;
+ while (*a && *a == *b) {
+ a++;
+ b++;
+ }
+ if (!*a)
+ return true;
+ j++;
+ }
+ }
+ return false;
+}
+
+/** similar to InList, but word s can be a substring of keyword.
+ * eg. the keyword define is defined as def~ine. This means the word must start
+ * with def to be a keyword, but also defi, defin and define are valid.
+ * The marker is ~ in this case.
+ */
+bool WordList::InListAbbreviated(const char *s, const char marker) const {
+ if (0 == words)
+ return false;
+ unsigned char firstChar = s[0];
+ int j = starts[firstChar];
+ if (j >= 0) {
+ while (words[j][0] == firstChar) {
+ bool isSubword = false;
+ int start = 1;
+ if (words[j][1] == marker) {
+ isSubword = true;
+ start++;
+ }
+ if (s[1] == words[j][start]) {
+ const char *a = words[j] + start;
+ const char *b = s + 1;
+ while (*a && *a == *b) {
+ a++;
+ if (*a == marker) {
+ isSubword = true;
+ a++;
+ }
+ b++;
+ }
+ if ((!*a || isSubword) && !*b)
+ return true;
+ }
+ j++;
+ }
+ }
+ j = starts['^'];
+ if (j >= 0) {
+ while (words[j][0] == '^') {
+ const char *a = words[j] + 1;
+ const char *b = s;
+ while (*a && *a == *b) {
+ a++;
+ b++;
+ }
+ if (!*a)
+ return true;
+ j++;
+ }
+ }
+ return false;
+}
diff --git a/plugins/scintilla/scintilla/WordList.h b/plugins/scintilla/scintilla/WordList.h
new file mode 100644
index 0000000..ea5be1d
--- /dev/null
+++ b/plugins/scintilla/scintilla/WordList.h
@@ -0,0 +1,41 @@
+// Scintilla source code edit control
+/** @file WordList.h
+ ** Hold a list of words.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef WORDLIST_H
+#define WORDLIST_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+/**
+ */
+class WordList {
+public:
+ // Each word contains at least one character - a empty word acts as sentinel at the end.
+ char **words;
+ char *list;
+ int len;
+ bool onlyLineEnds; ///< Delimited by any white space or only line ends
+ int starts[256];
+ WordList(bool onlyLineEnds_ = false) :
+ words(0), list(0), len(0), onlyLineEnds(onlyLineEnds_)
+ {}
+ ~WordList() { Clear(); }
+ operator bool() const { return len ? true : false; }
+ bool operator!=(const WordList &other) const;
+ void Clear();
+ void Set(const char *s);
+ bool InList(const char *s) const;
+ bool InListAbbreviated(const char *s, const char marker) const;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/XPM.cxx b/plugins/scintilla/scintilla/XPM.cxx
old mode 100755
new mode 100644
index 7fc05bb..d1389ef
--- a/plugins/scintilla/scintilla/XPM.cxx
+++ b/plugins/scintilla/scintilla/XPM.cxx
@@ -38,7 +38,7 @@ static size_t MeasureLength(const char *s) {
return i;
}
-ColourAllocated XPM::ColourFromCode(int ch) {
+ColourAllocated XPM::ColourFromCode(int ch) const {
return colourCodeTable[ch]->allocated;
#ifdef SLOW
for (int i=0; i<nColours; i++) {
@@ -62,7 +62,7 @@ XPM::XPM(const char *textForm) :
Init(textForm);
}
-XPM::XPM(const char * const *linesForm) :
+XPM::XPM(const char *const *linesForm) :
data(0), codes(0), colours(0), lines(0) {
Init(linesForm);
}
@@ -88,7 +88,7 @@ void XPM::Init(const char *textForm) {
}
}
-void XPM::Init(const char * const *linesForm) {
+void XPM::Init(const char *const *linesForm) {
Clear();
height = 1;
width = 1;
@@ -185,7 +185,7 @@ void XPM::Draw(Surface *surface, PRectangle &rc) {
// Centre the pixmap
int startY = rc.top + (rc.Height() - height) / 2;
int startX = rc.left + (rc.Width() - width) / 2;
- for (int y=0;y<height;y++) {
+ for (int y=0; y<height; y++) {
int prevCode = 0;
int xStartRun = 0;
for (int x=0; x<width; x++) {
diff --git a/plugins/scintilla/scintilla/XPM.h b/plugins/scintilla/scintilla/XPM.h
old mode 100755
new mode 100644
index 07cb580..cb05aae
--- a/plugins/scintilla/scintilla/XPM.h
+++ b/plugins/scintilla/scintilla/XPM.h
@@ -24,16 +24,16 @@ class XPM {
char codeTransparent;
char *codes;
ColourPair *colours;
- ColourAllocated ColourFromCode(int ch);
+ ColourAllocated ColourFromCode(int ch) const;
void FillRun(Surface *surface, int code, int startX, int y, int x);
char **lines;
ColourPair *colourCodeTable[256];
public:
XPM(const char *textForm);
- XPM(const char * const *linesForm);
+ XPM(const char *const *linesForm);
~XPM();
void Init(const char *textForm);
- void Init(const char * const *linesForm);
+ void Init(const char *const *linesForm);
void Clear();
/// Similar to same named method in ViewStyle:
void RefreshColourPalette(Palette &pal, bool want);
@@ -43,9 +43,9 @@ public:
void Draw(Surface *surface, PRectangle &rc);
char **InLinesForm() { return lines; }
void SetId(int pid_) { pid = pid_; }
- int GetId() { return pid; }
- int GetHeight() { return height; }
- int GetWidth() { return width; }
+ int GetId() const { return pid; }
+ int GetHeight() const { return height; }
+ int GetWidth() const { return width; }
static const char **LinesFormFromTextForm(const char *textForm);
};
diff --git a/plugins/scintilla/scintilla/include/HFacer.py b/plugins/scintilla/scintilla/include/HFacer.py
index 62a8273..074ce96 100755
--- a/plugins/scintilla/scintilla/include/HFacer.py
+++ b/plugins/scintilla/scintilla/include/HFacer.py
@@ -1,3 +1,4 @@
+#!/usr/bin/env python
# HFacer.py - regenerate the Scintilla.h and SciLexer.h files from the Scintilla.iface interface
# definition file.
# The header files are copied to a temporary file apart from the section between a /* ++Autogenerated*/
diff --git a/plugins/scintilla/scintilla/include/ILexer.h b/plugins/scintilla/scintilla/include/ILexer.h
new file mode 100644
index 0000000..b119ff6
--- /dev/null
+++ b/plugins/scintilla/scintilla/include/ILexer.h
@@ -0,0 +1,69 @@
+// Scintilla source code edit control
+/** @file ILexer.h
+ ** Interface between Scintilla and lexers.
+ **/
+// Copyright 1998-2010 by Neil Hodgson <neilh scintilla org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+#ifndef ILEXER_H
+#define ILEXER_H
+
+#ifdef SCI_NAMESPACE
+namespace Scintilla {
+#endif
+
+#ifdef _WIN32
+ #define SCI_METHOD __stdcall
+#else
+ #define SCI_METHOD
+#endif
+
+enum { dvOriginal=0 };
+
+class IDocument {
+public:
+ virtual int SCI_METHOD Version() const = 0;
+ virtual void SCI_METHOD SetErrorStatus(int status) = 0;
+ virtual int SCI_METHOD Length() const = 0;
+ virtual void SCI_METHOD GetCharRange(char *buffer, int position, int lengthRetrieve) const = 0;
+ virtual char SCI_METHOD StyleAt(int position) const = 0;
+ virtual int SCI_METHOD LineFromPosition(int position) const = 0;
+ virtual int SCI_METHOD LineStart(int line) const = 0;
+ virtual int SCI_METHOD GetLevel(int line) const = 0;
+ virtual int SCI_METHOD SetLevel(int line, int level) = 0;
+ virtual int SCI_METHOD GetLineState(int line) const = 0;
+ virtual int SCI_METHOD SetLineState(int line, int state) = 0;
+ virtual void SCI_METHOD StartStyling(int position, char mask) = 0;
+ virtual bool SCI_METHOD SetStyleFor(int length, char style) = 0;
+ virtual bool SCI_METHOD SetStyles(int length, const char *styles) = 0;
+ virtual void SCI_METHOD DecorationSetCurrentIndicator(int indicator) = 0;
+ virtual void SCI_METHOD DecorationFillRange(int position, int value, int fillLength) = 0;
+ virtual void SCI_METHOD ChangeLexerState(int start, int end) = 0;
+ virtual int SCI_METHOD CodePage() const = 0;
+ virtual bool SCI_METHOD IsDBCSLeadByte(char ch) const = 0;
+ virtual const char * SCI_METHOD BufferPointer() = 0;
+ virtual int SCI_METHOD GetLineIndentation(int line) = 0;
+};
+
+enum { lvOriginal=0 };
+
+class ILexer {
+public:
+ virtual int SCI_METHOD Version() const = 0;
+ virtual void SCI_METHOD Release() = 0;
+ virtual const char * SCI_METHOD PropertyNames() = 0;
+ virtual int SCI_METHOD PropertyType(const char *name) = 0;
+ virtual const char * SCI_METHOD DescribeProperty(const char *name) = 0;
+ virtual int SCI_METHOD PropertySet(const char *key, const char *val) = 0;
+ virtual const char * SCI_METHOD DescribeWordListSets() = 0;
+ virtual int SCI_METHOD WordListSet(int n, const char *wl) = 0;
+ virtual void SCI_METHOD Lex(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ virtual void SCI_METHOD Fold(unsigned int startPos, int lengthDoc, int initStyle, IDocument *pAccess) = 0;
+ virtual void * SCI_METHOD PrivateCall(int operation, void *pointer) = 0;
+};
+
+#ifdef SCI_NAMESPACE
+}
+#endif
+
+#endif
diff --git a/plugins/scintilla/scintilla/include/Platform.h b/plugins/scintilla/scintilla/include/Platform.h
index b5d6d9b..fd36a32 100644
--- a/plugins/scintilla/scintilla/include/Platform.h
+++ b/plugins/scintilla/scintilla/include/Platform.h
@@ -255,8 +255,8 @@ class Palette {
int allocatedLen;
#endif
// Private so Palette objects can not be copied
- Palette(const Palette &) {}
- Palette &operator=(const Palette &) { return *this; }
+ Palette(const Palette &);
+ Palette &operator=(const Palette &);
public:
#if PLAT_WIN
void *hpal;
@@ -288,8 +288,8 @@ protected:
int ascent;
#endif
// Private so Font objects can not be copied
- Font(const Font &) {}
- Font &operator=(const Font &) { fid=0; return *this; }
+ Font(const Font &);
+ Font &operator=(const Font &);
public:
Font();
virtual ~Font();
@@ -302,7 +302,7 @@ public:
// Alias another font - caller guarantees not to Release
void SetID(FontID fid_) { fid = fid_; }
friend class Surface;
- friend class SurfaceImpl;
+ friend class SurfaceImpl;
};
/**
@@ -314,8 +314,8 @@ private:
Surface(const Surface &) {}
Surface &operator=(const Surface &) { return *this; }
public:
- Surface() {};
- virtual ~Surface() {};
+ Surface() {}
+ virtual ~Surface() {}
static Surface *Allocate();
virtual void Init(WindowID wid)=0;
@@ -411,8 +411,8 @@ public:
void SetTitle(const char *s);
PRectangle GetMonitorRect(Point pt);
#if PLAT_MACOSX
- void SetWindow(void *ref) { windowRef = ref; };
- void SetControl(void *_control) { control = _control; };
+ void SetWindow(void *ref) { windowRef = ref; }
+ void SetControl(void *_control) { control = _control; }
#endif
private:
Cursor cursorLast;
@@ -474,7 +474,7 @@ public:
*/
class DynamicLibrary {
public:
- virtual ~DynamicLibrary() {};
+ virtual ~DynamicLibrary() {}
/// @return Pointer to function "name", or NULL on failure.
virtual Function FindFunction(const char *name) = 0;
diff --git a/plugins/scintilla/scintilla/include/SciLexer.h b/plugins/scintilla/scintilla/include/SciLexer.h
index ced86f4..1d5b69e 100644
--- a/plugins/scintilla/scintilla/include/SciLexer.h
+++ b/plugins/scintilla/scintilla/include/SciLexer.h
@@ -111,6 +111,9 @@
#define SCLEX_NIMROD 96
#define SCLEX_SML 97
#define SCLEX_MARKDOWN 98
+#define SCLEX_TXT2TAGS 99
+#define SCLEX_A68K 100
+#define SCLEX_MODULA 101
#define SCLEX_AUTOMATIC 1000
#define SCE_P_DEFAULT 0
#define SCE_P_COMMENTLINE 1
@@ -148,6 +151,8 @@
#define SCE_C_COMMENTDOCKEYWORD 17
#define SCE_C_COMMENTDOCKEYWORDERROR 18
#define SCE_C_GLOBALCLASS 19
+#define SCE_C_STRINGRAW 20
+#define SCE_C_TRIPLEVERBATIM 21
#define SCE_D_DEFAULT 0
#define SCE_D_COMMENT 1
#define SCE_D_COMMENTLINE 2
@@ -600,6 +605,7 @@
#define SCE_ASM_CHARACTER 12
#define SCE_ASM_STRINGEOL 13
#define SCE_ASM_EXTINSTRUCTION 14
+#define SCE_ASM_COMMENTDIRECTIVE 15
#define SCE_F_DEFAULT 0
#define SCE_F_COMMENT 1
#define SCE_F_NUMBER 2
@@ -637,6 +643,7 @@
#define SCE_CSS_EXTENDED_IDENTIFIER 19
#define SCE_CSS_EXTENDED_PSEUDOCLASS 20
#define SCE_CSS_EXTENDED_PSEUDOELEMENT 21
+#define SCE_CSS_MEDIA 22
#define SCE_POV_DEFAULT 0
#define SCE_POV_COMMENT 1
#define SCE_POV_COMMENTLINE 2
@@ -1081,11 +1088,19 @@
#define SCE_FS_DATE 16
#define SCE_FS_STRINGEOL 17
#define SCE_FS_CONSTANT 18
-#define SCE_FS_ASM 19
-#define SCE_FS_LABEL 20
-#define SCE_FS_ERROR 21
-#define SCE_FS_HEXNUMBER 22
-#define SCE_FS_BINNUMBER 23
+#define SCE_FS_WORDOPERATOR 19
+#define SCE_FS_DISABLEDCODE 20
+#define SCE_FS_DEFAULT_C 21
+#define SCE_FS_COMMENTDOC_C 22
+#define SCE_FS_COMMENTLINEDOC_C 23
+#define SCE_FS_KEYWORD_C 24
+#define SCE_FS_KEYWORD2_C 25
+#define SCE_FS_NUMBER_C 26
+#define SCE_FS_STRING_C 27
+#define SCE_FS_PREPROCESSOR_C 28
+#define SCE_FS_OPERATOR_C 29
+#define SCE_FS_IDENTIFIER_C 30
+#define SCE_FS_STRINGEOL_C 31
#define SCE_CSOUND_DEFAULT 0
#define SCE_CSOUND_COMMENT 1
#define SCE_CSOUND_NUMBER 2
@@ -1266,6 +1281,9 @@
#define SCE_POWERSHELL_KEYWORD 8
#define SCE_POWERSHELL_CMDLET 9
#define SCE_POWERSHELL_ALIAS 10
+#define SCE_POWERSHELL_FUNCTION 11
+#define SCE_POWERSHELL_USER1 12
+#define SCE_POWERSHELL_COMMENTSTREAM 13
#define SCE_MYSQL_DEFAULT 0
#define SCE_MYSQL_COMMENT 1
#define SCE_MYSQL_COMMENTLINE 2
@@ -1376,6 +1394,69 @@
#define SCE_MARKDOWN_CODE 19
#define SCE_MARKDOWN_CODE2 20
#define SCE_MARKDOWN_CODEBK 21
+#define SCE_TXT2TAGS_DEFAULT 0
+#define SCE_TXT2TAGS_LINE_BEGIN 1
+#define SCE_TXT2TAGS_STRONG1 2
+#define SCE_TXT2TAGS_STRONG2 3
+#define SCE_TXT2TAGS_EM1 4
+#define SCE_TXT2TAGS_EM2 5
+#define SCE_TXT2TAGS_HEADER1 6
+#define SCE_TXT2TAGS_HEADER2 7
+#define SCE_TXT2TAGS_HEADER3 8
+#define SCE_TXT2TAGS_HEADER4 9
+#define SCE_TXT2TAGS_HEADER5 10
+#define SCE_TXT2TAGS_HEADER6 11
+#define SCE_TXT2TAGS_PRECHAR 12
+#define SCE_TXT2TAGS_ULIST_ITEM 13
+#define SCE_TXT2TAGS_OLIST_ITEM 14
+#define SCE_TXT2TAGS_BLOCKQUOTE 15
+#define SCE_TXT2TAGS_STRIKEOUT 16
+#define SCE_TXT2TAGS_HRULE 17
+#define SCE_TXT2TAGS_LINK 18
+#define SCE_TXT2TAGS_CODE 19
+#define SCE_TXT2TAGS_CODE2 20
+#define SCE_TXT2TAGS_CODEBK 21
+#define SCE_TXT2TAGS_COMMENT 22
+#define SCE_TXT2TAGS_OPTION 23
+#define SCE_TXT2TAGS_PREPROC 24
+#define SCE_TXT2TAGS_POSTPROC 25
+#define SCE_A68K_DEFAULT 0
+#define SCE_A68K_COMMENT 1
+#define SCE_A68K_NUMBER_DEC 2
+#define SCE_A68K_NUMBER_BIN 3
+#define SCE_A68K_NUMBER_HEX 4
+#define SCE_A68K_STRING1 5
+#define SCE_A68K_OPERATOR 6
+#define SCE_A68K_CPUINSTRUCTION 7
+#define SCE_A68K_EXTINSTRUCTION 8
+#define SCE_A68K_REGISTER 9
+#define SCE_A68K_DIRECTIVE 10
+#define SCE_A68K_MACRO_ARG 11
+#define SCE_A68K_LABEL 12
+#define SCE_A68K_STRING2 13
+#define SCE_A68K_IDENTIFIER 14
+#define SCE_A68K_MACRO_DECLARATION 15
+#define SCE_A68K_COMMENT_WORD 16
+#define SCE_A68K_COMMENT_SPECIAL 17
+#define SCE_A68K_COMMENT_DOXYGEN 18
+#define SCE_MODULA_DEFAULT 0
+#define SCE_MODULA_COMMENT 1
+#define SCE_MODULA_DOXYCOMM 2
+#define SCE_MODULA_DOXYKEY 3
+#define SCE_MODULA_KEYWORD 4
+#define SCE_MODULA_RESERVED 5
+#define SCE_MODULA_NUMBER 6
+#define SCE_MODULA_BASENUM 7
+#define SCE_MODULA_FLOAT 8
+#define SCE_MODULA_STRING 9
+#define SCE_MODULA_STRSPEC 10
+#define SCE_MODULA_CHAR 11
+#define SCE_MODULA_CHARSPEC 12
+#define SCE_MODULA_PROC 13
+#define SCE_MODULA_PRAGMA 14
+#define SCE_MODULA_PRGKEY 15
+#define SCE_MODULA_OPERATOR 16
+#define SCE_MODULA_BADSTR 17
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
#endif
diff --git a/plugins/scintilla/scintilla/include/Scintilla.h b/plugins/scintilla/scintilla/include/Scintilla.h
index 2359212..f1c4fa9 100644
--- a/plugins/scintilla/scintilla/include/Scintilla.h
+++ b/plugins/scintilla/scintilla/include/Scintilla.h
@@ -11,18 +11,14 @@
#ifndef SCINTILLA_H
#define SCINTILLA_H
-#if LCCWIN
-typedef BOOL bool;
-#endif
-
#ifdef __cplusplus
extern "C" {
#endif
-#if PLAT_WIN
+#if defined(_WIN32)
/* Return false on failure: */
-bool Scintilla_RegisterClasses(void *hInstance);
-bool Scintilla_ReleaseResources();
+int Scintilla_RegisterClasses(void *hInstance);
+int Scintilla_ReleaseResources();
#endif
int Scintilla_LinkLexers();
@@ -36,11 +32,6 @@ int Scintilla_LinkLexers();
#if defined(_WIN32)
#include <basetsd.h>
#endif
-#ifdef HAVE_STDINT_H
-#include <stdint.h>
-typedef uintptr_t uptr_t;
-typedef intptr_t sptr_t;
-#else
#ifdef MAXULONG_PTR
typedef ULONG_PTR uptr_t;
typedef LONG_PTR sptr_t;
@@ -48,7 +39,6 @@ typedef LONG_PTR sptr_t;
typedef unsigned long uptr_t;
typedef long sptr_t;
#endif
-#endif
typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam, sptr_t lParam);
@@ -101,7 +91,6 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_SETTABWIDTH 2036
#define SCI_GETTABWIDTH 2121
#define SC_CP_UTF8 65001
-#define SC_CP_DBCS 1
#define SCI_SETCODEPAGE 2037
#define SCI_SETUSEPALETTE 2039
#define MARKER_MAX 31
@@ -147,6 +136,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MARKERDEFINE 2040
#define SCI_MARKERSETFORE 2041
#define SCI_MARKERSETBACK 2042
+#define SCI_MARKERSETBACKSELECTED 2292
+#define SCI_MARKERENABLEHIGHLIGHT 2293
#define SCI_MARKERADD 2043
#define SCI_MARKERDELETE 2044
#define SCI_MARKERDELETEALL 2045
@@ -170,6 +161,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETMARGINMASKN 2245
#define SCI_SETMARGINSENSITIVEN 2246
#define SCI_GETMARGINSENSITIVEN 2247
+#define SCI_SETMARGINCURSORN 2248
+#define SCI_GETMARGINCURSORN 2249
#define STYLE_DEFAULT 32
#define STYLE_LINENUMBER 33
#define STYLE_BRACELIGHT 34
@@ -254,6 +247,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define INDIC_HIDDEN 5
#define INDIC_BOX 6
#define INDIC_ROUNDBOX 7
+#define INDIC_STRAIGHTBOX 8
#define INDIC_MAX 31
#define INDIC_CONTAINER 8
#define INDIC0_MASK 0x20
@@ -492,6 +486,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_SETFONTQUALITY 2611
#define SCI_GETFONTQUALITY 2612
#define SCI_SETFIRSTVISIBLELINE 2613
+#define SC_MULTIPASTE_ONCE 0
+#define SC_MULTIPASTE_EACH 1
+#define SCI_SETMULTIPASTE 2614
+#define SCI_GETMULTIPASTE 2615
+#define SCI_GETTAG 2616
#define SCI_TARGETFROMSELECTION 2287
#define SCI_LINESJOIN 2288
#define SCI_LINESSPLIT 2289
@@ -558,7 +557,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_MOVECARETINSIDEVIEW 2401
#define SCI_LINELENGTH 2350
#define SCI_BRACEHIGHLIGHT 2351
+#define SCI_BRACEHIGHLIGHTINDICATOR 2498
#define SCI_BRACEBADLIGHT 2352
+#define SCI_BRACEBADLIGHTINDICATOR 2499
#define SCI_BRACEMATCH 2353
#define SCI_GETVIEWEOL 2355
#define SCI_SETVIEWEOL 2356
@@ -596,7 +597,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_SETMOUSEDOWNCAPTURES 2384
#define SCI_GETMOUSEDOWNCAPTURES 2385
#define SC_CURSORNORMAL -1
+#define SC_CURSORARROW 2
#define SC_CURSORWAIT 4
+#define SC_CURSORREVERSEARROW 7
#define SCI_SETCURSOR 2386
#define SCI_GETCURSOR 2387
#define SCI_SETCONTROLCHARSYMBOL 2388
@@ -674,6 +677,9 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_FINDCOLUMN 2456
#define SCI_GETCARETSTICKY 2457
#define SCI_SETCARETSTICKY 2458
+#define SC_CARETSTICKY_OFF 0
+#define SC_CARETSTICKY_ON 1
+#define SC_CARETSTICKY_WHITESPACE 2
#define SCI_TOGGLECARETSTICKY 2459
#define SCI_SETPASTECONVERTENDINGS 2467
#define SCI_GETPASTECONVERTENDINGS 2468
@@ -706,6 +712,8 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETKEYSUNICODE 2522
#define SCI_INDICSETALPHA 2523
#define SCI_INDICGETALPHA 2524
+#define SCI_INDICSETOUTLINEALPHA 2558
+#define SCI_INDICGETOUTLINEALPHA 2559
#define SCI_SETEXTRAASCENT 2525
#define SCI_GETEXTRAASCENT 2526
#define SCI_SETEXTRADESCENT 2527
@@ -788,6 +796,11 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETADDITIONALCARETFORE 2605
#define SCI_ROTATESELECTION 2606
#define SCI_SWAPMAINANCHORCARET 2607
+#define SCI_CHANGELEXERSTATE 2617
+#define SCI_CONTRACTEDFOLDNEXT 2618
+#define SCI_VERTICALCENTRECARET 2619
+#define SCI_MOVESELECTEDLINESUP 2620
+#define SCI_MOVESELECTEDLINESDOWN 2621
#define SCI_STARTRECORD 3001
#define SCI_STOPRECORD 3002
#define SCI_SETLEXER 4001
@@ -803,6 +816,14 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCI_GETPROPERTYINT 4010
#define SCI_GETSTYLEBITSNEEDED 4011
#define SCI_GETLEXERLANGUAGE 4012
+#define SCI_PRIVATELEXERCALL 4013
+#define SCI_PROPERTYNAMES 4014
+#define SC_TYPE_BOOLEAN 0
+#define SC_TYPE_INTEGER 1
+#define SC_TYPE_STRING 2
+#define SCI_PROPERTYTYPE 4015
+#define SCI_DESCRIBEPROPERTY 4016
+#define SCI_DESCRIBEKEYWORDSETS 4017
#define SC_MOD_INSERTTEXT 0x1
#define SC_MOD_DELETETEXT 0x2
#define SC_MOD_CHANGESTYLE 0x4
@@ -822,7 +843,12 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SC_MOD_CHANGEMARGIN 0x10000
#define SC_MOD_CHANGEANNOTATION 0x20000
#define SC_MOD_CONTAINER 0x40000
-#define SC_MODEVENTMASKALL 0x7FFFF
+#define SC_MOD_LEXERSTATE 0x80000
+#define SC_MODEVENTMASKALL 0xFFFFF
+#define SC_UPDATE_CONTENT 0x1
+#define SC_UPDATE_SELECTION 0x2
+#define SC_UPDATE_V_SCROLL 0x4
+#define SC_UPDATE_H_SCROLL 0x8
#define SCEN_CHANGE 768
#define SCEN_SETFOCUS 512
#define SCEN_KILLFOCUS 256
@@ -877,6 +903,7 @@ typedef sptr_t (*SciFnDirect)(sptr_t ptr, unsigned int iMessage, uptr_t wParam,
#define SCN_INDICATORRELEASE 2024
#define SCN_AUTOCCANCELLED 2025
#define SCN_AUTOCCHARDELETED 2026
+#define SCN_HOTSPOTRELEASECLICK 2027
/* --Autogenerated -- end of section automatically generated from Scintilla.iface */
/* These structures are defined to be exactly the same shape as the Win32
@@ -907,23 +934,28 @@ struct Sci_TextToFind {
#define TextRange Sci_TextRange
#define TextToFind Sci_TextToFind
-#ifdef PLATFORM_H
+typedef void *Sci_SurfaceID;
+
+struct Sci_Rectangle {
+ int left;
+ int top;
+ int right;
+ int bottom;
+};
/* This structure is used in printing and requires some of the graphics types
* from Platform.h. Not needed by most client code. */
struct Sci_RangeToFormat {
- SurfaceID hdc;
- SurfaceID hdcTarget;
- PRectangle rc;
- PRectangle rcPage;
- Sci_CharacterRange chrg;
+ Sci_SurfaceID hdc;
+ Sci_SurfaceID hdcTarget;
+ struct Sci_Rectangle rc;
+ struct Sci_Rectangle rcPage;
+ struct Sci_CharacterRange chrg;
};
#define RangeToFormat Sci_RangeToFormat
-#endif
-
struct Sci_NotifyHeader {
/* Compatible with Windows NMHDR.
* hwndFrom is really an environment specific window handle or pointer
@@ -937,11 +969,22 @@ struct Sci_NotifyHeader {
struct SCNotification {
struct Sci_NotifyHeader nmhdr;
- int position; /* SCN_STYLENEEDED, SCN_MODIFIED, SCN_DWELLSTART, SCN_DWELLEND */
+ int position;
+ /* SCN_STYLENEEDED, SCN_DOUBLECLICK, SCN_MODIFIED, SCN_MARGINCLICK, */
+ /* SCN_NEEDSHOWN, SCN_DWELLSTART, SCN_DWELLEND, SCN_CALLTIPCLICK, */
+ /* SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, SCN_HOTSPOTRELEASECLICK, */
+ /* SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
+ /* SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
+
int ch; /* SCN_CHARADDED, SCN_KEY */
- int modifiers; /* SCN_KEY */
+ int modifiers;
+ /* SCN_KEY, SCN_DOUBLECLICK, SCN_HOTSPOTCLICK, SCN_HOTSPOTDOUBLECLICK, */
+ /* SCN_HOTSPOTRELEASECLICK, SCN_INDICATORCLICK, SCN_INDICATORRELEASE, */
+
int modificationType; /* SCN_MODIFIED */
- const char *text; /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION */
+ const char *text;
+ /* SCN_MODIFIED, SCN_USERLISTSELECTION, SCN_AUTOCSELECTION, SCN_URIDROPPED */
+
int length; /* SCN_MODIFIED */
int linesAdded; /* SCN_MODIFIED */
int message; /* SCN_MACRORECORD */
@@ -955,11 +998,18 @@ struct SCNotification {
int x; /* SCN_DWELLSTART, SCN_DWELLEND */
int y; /* SCN_DWELLSTART, SCN_DWELLEND */
int token; /* SCN_MODIFIED with SC_MOD_CONTAINER */
- int annotationLinesAdded; /* SC_MOD_CHANGEANNOTATION */
+ int annotationLinesAdded; /* SCN_MODIFIED with SC_MOD_CHANGEANNOTATION */
+ int updated; /* SCN_UPDATEUI */
};
#ifdef SCI_NAMESPACE
}
#endif
+#ifdef INCLUDE_DEPRECATED_FEATURES
+
+#define SC_CP_DBCS 1
+
+#endif
+
#endif
diff --git a/plugins/scintilla/scintilla/include/Scintilla.iface b/plugins/scintilla/scintilla/include/Scintilla.iface
old mode 100755
new mode 100644
index f2c8f1e..8cd3ab5
--- a/plugins/scintilla/scintilla/include/Scintilla.iface
+++ b/plugins/scintilla/scintilla/include/Scintilla.iface
@@ -224,9 +224,6 @@ get int GetTabWidth=2121(,)
# This is the same value as CP_UTF8 in Windows
val SC_CP_UTF8=65001
-# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
-val SC_CP_DBCS=1
-
# Set the code page used to interpret the bytes of the document as characters.
# The SC_CP_UTF8 value can be used to enter Unicode mode.
set void SetCodePage=2037(int codePage,)
@@ -262,7 +259,7 @@ val SC_MARK_CIRCLEPLUSCONNECTED=19
val SC_MARK_CIRCLEMINUS=20
val SC_MARK_CIRCLEMINUSCONNECTED=21
-# Invisible mark that only sets the line background color.
+# Invisible mark that only sets the line background colour.
val SC_MARK_BACKGROUND=22
val SC_MARK_DOTDOTDOT=23
val SC_MARK_ARROWS=24
@@ -295,6 +292,12 @@ fun 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 the background colour used for a particular marker number when its folding block is selected.
+fun 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,)
+
# Add a marker to a line, returning an ID which can be used to find or delete the marker.
fun int MarkerAdd=2043(int line, int markerNumber)
@@ -307,7 +310,8 @@ fun void MarkerDeleteAll=2045(int markerNumber,)
# Get a bit mask of all the markers set on a line.
fun int MarkerGet=2046(int line,)
-# Find the next line after lineStart that includes a marker in mask.
+# Find the next line at or after lineStart that includes a marker in mask.
+# Return -1 when no more lines.
fun int MarkerNext=2047(int lineStart, int markerMask)
# Find the previous line before lineStart that includes a marker in mask.
@@ -354,6 +358,12 @@ set void SetMarginSensitiveN=2246(int margin, bool sensitive)
# Retrieve the mouse click sensitivity of a margin.
get bool GetMarginSensitiveN=2247(int margin,)
+# Set the cursor shown when the mouse is inside a margin.
+set void SetMarginCursorN=2248(int margin, int cursor)
+
+# Retrieve the cursor shown in a margin.
+get int GetMarginCursorN=2249(int margin,)
+
# Styles in range 32..38 are predefined for parts of the UI and are not used as normal styles.
# Style 39 is for future use.
enu StylesCommon=STYLE_
@@ -540,6 +550,7 @@ val INDIC_STRIKE=4
val INDIC_HIDDEN=5
val INDIC_BOX=6
val INDIC_ROUNDBOX=7
+val INDIC_STRAIGHTBOX=8
val INDIC_MAX=31
val INDIC_CONTAINER=8
val INDIC0_MASK=0x20
@@ -1223,6 +1234,19 @@ get int GetFontQuality=2612(,)
# Scroll so that a display line is at the top of the display.
set void SetFirstVisibleLine=2613(int lineDisplay,)
+enu MultiPaste=SC_MULTIPASTE_
+val SC_MULTIPASTE_ONCE=0
+val SC_MULTIPASTE_EACH=1
+
+# Change the effect of pasting when there are multiple selections.
+set void SetMultiPaste=2614(int multiPaste,)
+
+# Retrieve the effect of pasting when there are multiple selections..
+get int GetMultiPaste=2615(,)
+
+# Retrieve the value of a tag from a regular expression search.
+fun 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(,)
@@ -1423,9 +1447,15 @@ fun int LineLength=2350(int line,)
# Highlight the characters at two positions.
fun void BraceHighlight=2351(position pos1, position pos2)
+# Use specified indicator to highlight matching braces instead of changing their style.
+fun void BraceHighlightIndicator=2498(bool useBraceHighlightIndicator, int indicator)
+
# Highlight the character at a position indicating there is no matching brace.
fun void BraceBadLight=2352(position pos,)
+# Use specified indicator to highlight non matching brace instead of changing its style.
+fun void BraceBadLightIndicator=2499(bool useBraceBadLightIndicator, int indicator)
+
# Find the position of a matching brace or INVALID_POSITION if no match.
fun position BraceMatch=2353(position pos,)
@@ -1529,7 +1559,9 @@ get bool GetMouseDownCaptures=2385(,)
enu CursorShape=SC_CURSOR
val SC_CURSORNORMAL=-1
+val SC_CURSORARROW=2
val SC_CURSORWAIT=4
+val SC_CURSORREVERSEARROW=7
# Sets the cursor to one of the SC_CURSOR* values.
set void SetCursor=2386(int cursorType,)
# Get cursor type.
@@ -1767,10 +1799,15 @@ fun int EncodedFromUTF8=2449(string utf8, stringresult encoded)
fun int FindColumn=2456(int line, int column)
# Can the caret preferred x position only be changed by explicit movement commands?
-get bool GetCaretSticky=2457(,)
+get int GetCaretSticky=2457(,)
# Stop the caret preferred x position changing when the user types.
-set void SetCaretSticky=2458(bool useCaretStickyBehaviour,)
+set void SetCaretSticky=2458(int useCaretStickyBehaviour,)
+
+enu CaretSticky=SC_CARETSTICKY_
+val SC_CARETSTICKY_OFF=0
+val SC_CARETSTICKY_ON=1
+val SC_CARETSTICKY_WHITESPACE=2
# Switch between sticky and non-sticky: meant to be bound to a key.
fun void ToggleCaretSticky=2459(,)
@@ -1860,6 +1897,12 @@ set void IndicSetAlpha=2523(int indicator, int alpha)
# Get the alpha fill colour of the given indicator.
get int IndicGetAlpha=2524(int indicator,)
+# Set the alpha outline colour of the given indicator.
+set void IndicSetOutlineAlpha=2558(int indicator, int alpha)
+
+# Get the alpha outline colour of the given indicator.
+get int IndicGetOutlineAlpha=2559(int indicator,)
+
# Set extra ascent for each line
set void SetExtraAscent=2525(int extraAscent,)
@@ -2071,6 +2114,23 @@ fun void RotateSelection=2606(,)
# Swap that caret and anchor of the main selection.
fun void SwapMainAnchorCaret=2607(,)
+# Indicate that the internal state of a lexer has changed over a range and therefore
+# there may be a need to redraw.
+fun int ChangeLexerState=2617(position start, position end)
+
+# Find the next line at or after lineStart that is a contracted fold header line.
+# Return -1 when no more lines.
+fun int ContractedFoldNext=2618(int lineStart,)
+
+# Centre current line in window.
+fun void VerticalCentreCaret=2619(,)
+
+# Move the selected lines up one line, shifting the line above after the selection
+fun void MoveSelectedLinesUp=2620(,)
+
+# Move the selected lines down one line, shifting the line below before the selection
+fun void MoveSelectedLinesDown=2621(,)
+
# Start notifying the container of all key presses and commands.
fun void StartRecord=3001(,)
@@ -2119,6 +2179,26 @@ get int GetStyleBitsNeeded=4011(,)
# Return the length of the text.
get int GetLexerLanguage=4012(, stringresult text)
+# For private communication between an application and a known lexer.
+fun int PrivateLexerCall=4013(int operation, int pointer)
+
+# Retrieve a '\n' separated list of properties understood by the current lexer.
+fun int PropertyNames=4014(, stringresult names)
+
+enu TypeProperty=SC_TYPE_
+val SC_TYPE_BOOLEAN=0
+val SC_TYPE_INTEGER=1
+val SC_TYPE_STRING=2
+
+# Retrieve the type of a property.
+fun int PropertyType=4015(string name,)
+
+# Describe a property.
+fun int DescribeProperty=4016(string name, stringresult description)
+
+# Retrieve a '\n' separated list of descriptions of the keyword sets understood by the current lexer.
+fun int DescribeKeyWordSets=4017(, stringresult descriptions)
+
# Notifications
# Type of modification and the action which caused the modification.
# These are defined as a bit mask to make it easy to specify which notifications are wanted.
@@ -2143,7 +2223,14 @@ val SC_MOD_CHANGELINESTATE=0x8000
val SC_MOD_CHANGEMARGIN=0x10000
val SC_MOD_CHANGEANNOTATION=0x20000
val SC_MOD_CONTAINER=0x40000
-val SC_MODEVENTMASKALL=0x7FFFF
+val SC_MOD_LEXERSTATE=0x80000
+val SC_MODEVENTMASKALL=0xFFFFF
+
+enu Update=SC_UPDATE_
+val SC_UPDATE_CONTENT=0x1
+val SC_UPDATE_SELECTION=0x2
+val SC_UPDATE_V_SCROLL=0x4
+val SC_UPDATE_H_SCROLL=0x8
# For compatibility, these go through the COMMAND notification rather than NOTIFY
# and should have had exactly the same values as the EN_* constants.
@@ -2286,6 +2373,9 @@ val SCLEX_POWERPRO=95
val SCLEX_NIMROD=96
val SCLEX_SML=97
val SCLEX_MARKDOWN=98
+val SCLEX_TXT2TAGS=99
+val SCLEX_A68K=100
+val SCLEX_MODULA=101
# When a lexer specifies its language as SCLEX_AUTOMATIC it receives a
# value assigned in sequence from SCLEX_AUTOMATIC+1.
@@ -2332,6 +2422,8 @@ val SCE_C_WORD2=16
val SCE_C_COMMENTDOCKEYWORD=17
val SCE_C_COMMENTDOCKEYWORDERROR=18
val SCE_C_GLOBALCLASS=19
+val SCE_C_STRINGRAW=20
+val SCE_C_TRIPLEVERBATIM=21
# Lexical states for SCLEX_D
lex D=SCLEX_D SCE_D_
val SCE_D_DEFAULT=0
@@ -2851,6 +2943,7 @@ val SCE_ASM_COMMENTBLOCK=11
val SCE_ASM_CHARACTER=12
val SCE_ASM_STRINGEOL=13
val SCE_ASM_EXTINSTRUCTION=14
+val SCE_ASM_COMMENTDIRECTIVE=15
# Lexical states for SCLEX_FORTRAN
lex Fortran=SCLEX_FORTRAN SCE_F_
lex F77=SCLEX_F77 SCE_F_
@@ -2893,6 +2986,7 @@ val SCE_CSS_PSEUDOELEMENT=18
val SCE_CSS_EXTENDED_IDENTIFIER=19
val SCE_CSS_EXTENDED_PSEUDOCLASS=20
val SCE_CSS_EXTENDED_PSEUDOELEMENT=21
+val SCE_CSS_MEDIA=22
# Lexical states for SCLEX_POV
lex POV=SCLEX_POV SCE_POV_
val SCE_POV_DEFAULT=0
@@ -3375,7 +3469,7 @@ val SCE_ST_ASSIGN=14
val SCE_ST_CHARACTER=15
val SCE_ST_SPEC_SEL=16
# Lexical states for SCLEX_FLAGSHIP (clipper)
-lex FlagShip=SCLEX_FLAGSHIP SCE_B_
+lex FlagShip=SCLEX_FLAGSHIP SCE_FS_
val SCE_FS_DEFAULT=0
val SCE_FS_COMMENT=1
val SCE_FS_COMMENTLINE=2
@@ -3395,11 +3489,19 @@ val SCE_FS_IDENTIFIER=15
val SCE_FS_DATE=16
val SCE_FS_STRINGEOL=17
val SCE_FS_CONSTANT=18
-val SCE_FS_ASM=19
-val SCE_FS_LABEL=20
-val SCE_FS_ERROR=21
-val SCE_FS_HEXNUMBER=22
-val SCE_FS_BINNUMBER=23
+val SCE_FS_WORDOPERATOR=19
+val SCE_FS_DISABLEDCODE=20
+val SCE_FS_DEFAULT_C=21
+val SCE_FS_COMMENTDOC_C=22
+val SCE_FS_COMMENTLINEDOC_C=23
+val SCE_FS_KEYWORD_C=24
+val SCE_FS_KEYWORD2_C=25
+val SCE_FS_NUMBER_C=26
+val SCE_FS_STRING_C=27
+val SCE_FS_PREPROCESSOR_C=28
+val SCE_FS_OPERATOR_C=29
+val SCE_FS_IDENTIFIER_C=30
+val SCE_FS_STRINGEOL_C=31
# Lexical states for SCLEX_CSOUND
lex Csound=SCLEX_CSOUND SCE_CSOUND_
val SCE_CSOUND_DEFAULT=0
@@ -3606,6 +3708,9 @@ val SCE_POWERSHELL_IDENTIFIER=7
val SCE_POWERSHELL_KEYWORD=8
val SCE_POWERSHELL_CMDLET=9
val SCE_POWERSHELL_ALIAS=10
+val SCE_POWERSHELL_FUNCTION=11
+val SCE_POWERSHELL_USER1=12
+val SCE_POWERSHELL_COMMENTSTREAM=13
# Lexical state for SCLEX_MYSQL
lex MySQL=SCLEX_MYSQL SCE_MYSQL_
val SCE_MYSQL_DEFAULT=0
@@ -3730,6 +3835,75 @@ val SCE_MARKDOWN_LINK=18
val SCE_MARKDOWN_CODE=19
val SCE_MARKDOWN_CODE2=20
val SCE_MARKDOWN_CODEBK=21
+# Lexical state for SCLEX_TXT2TAGS
+lex Txt2tags=SCLEX_TXT2TAGS SCE_TXT2TAGS_
+val SCE_TXT2TAGS_DEFAULT=0
+val SCE_TXT2TAGS_LINE_BEGIN=1
+val SCE_TXT2TAGS_STRONG1=2
+val SCE_TXT2TAGS_STRONG2=3
+val SCE_TXT2TAGS_EM1=4
+val SCE_TXT2TAGS_EM2=5
+val SCE_TXT2TAGS_HEADER1=6
+val SCE_TXT2TAGS_HEADER2=7
+val SCE_TXT2TAGS_HEADER3=8
+val SCE_TXT2TAGS_HEADER4=9
+val SCE_TXT2TAGS_HEADER5=10
+val SCE_TXT2TAGS_HEADER6=11
+val SCE_TXT2TAGS_PRECHAR=12
+val SCE_TXT2TAGS_ULIST_ITEM=13
+val SCE_TXT2TAGS_OLIST_ITEM=14
+val SCE_TXT2TAGS_BLOCKQUOTE=15
+val SCE_TXT2TAGS_STRIKEOUT=16
+val SCE_TXT2TAGS_HRULE=17
+val SCE_TXT2TAGS_LINK=18
+val SCE_TXT2TAGS_CODE=19
+val SCE_TXT2TAGS_CODE2=20
+val SCE_TXT2TAGS_CODEBK=21
+val SCE_TXT2TAGS_COMMENT=22
+val SCE_TXT2TAGS_OPTION=23
+val SCE_TXT2TAGS_PREPROC=24
+val SCE_TXT2TAGS_POSTPROC=25
+# Lexical states for SCLEX_A68K
+lex A68k=SCLEX_A68K SCE_A68K_
+val SCE_A68K_DEFAULT=0
+val SCE_A68K_COMMENT=1
+val SCE_A68K_NUMBER_DEC=2
+val SCE_A68K_NUMBER_BIN=3
+val SCE_A68K_NUMBER_HEX=4
+val SCE_A68K_STRING1=5
+val SCE_A68K_OPERATOR=6
+val SCE_A68K_CPUINSTRUCTION=7
+val SCE_A68K_EXTINSTRUCTION=8
+val SCE_A68K_REGISTER=9
+val SCE_A68K_DIRECTIVE=10
+val SCE_A68K_MACRO_ARG=11
+val SCE_A68K_LABEL=12
+val SCE_A68K_STRING2=13
+val SCE_A68K_IDENTIFIER=14
+val SCE_A68K_MACRO_DECLARATION=15
+val SCE_A68K_COMMENT_WORD=16
+val SCE_A68K_COMMENT_SPECIAL=17
+val SCE_A68K_COMMENT_DOXYGEN=18
+# Lexical states for SCLEX_MODULA
+lex Modula=SCLEX_MODULA SCE_MODULA_
+val SCE_MODULA_DEFAULT=0
+val SCE_MODULA_COMMENT=1
+val SCE_MODULA_DOXYCOMM=2
+val SCE_MODULA_DOXYKEY=3
+val SCE_MODULA_KEYWORD=4
+val SCE_MODULA_RESERVED=5
+val SCE_MODULA_NUMBER=6
+val SCE_MODULA_BASENUM=7
+val SCE_MODULA_FLOAT=8
+val SCE_MODULA_STRING=9
+val SCE_MODULA_STRSPEC=10
+val SCE_MODULA_CHAR=11
+val SCE_MODULA_CHARSPEC=12
+val SCE_MODULA_PROC=13
+val SCE_MODULA_PRAGMA=14
+val SCE_MODULA_PRGKEY=15
+val SCE_MODULA_OPERATOR=16
+val SCE_MODULA_BADSTR=17
# Events
@@ -3740,23 +3914,30 @@ evt void SavePointLeft=2003(void)
evt void ModifyAttemptRO=2004(void)
# GTK+ Specific to work around focus and accelerator problems:
evt void Key=2005(int ch, int modifiers)
-evt void DoubleClick=2006(void)
-evt void UpdateUI=2007(void)
-evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev)
+evt void DoubleClick=2006(int modifiers, int position, int line)
+evt void UpdateUI=2007(int updated)
+evt void Modified=2008(int position, int modificationType, string text, int length, int linesAdded, int line, int foldLevelNow, int foldLevelPrev, int token, int annotationLinesAdded)
evt void MacroRecord=2009(int message, int wParam, int lParam)
evt void MarginClick=2010(int modifiers, int position, int margin)
evt void NeedShown=2011(int position, int length)
evt void Painted=2013(void)
-evt void UserListSelection=2014(int listType, string text)
+evt void UserListSelection=2014(int listType, string text, int position)
evt void URIDropped=2015(string text)
-evt void DwellStart=2016(int position)
-evt void DwellEnd=2017(int position)
+evt void DwellStart=2016(int position, int x, int y)
+evt void DwellEnd=2017(int position, int x, int y)
evt void Zoom=2018(void)
evt void HotSpotClick=2019(int modifiers, int position)
evt void HotSpotDoubleClick=2020(int modifiers, int position)
evt void CallTipClick=2021(int position)
-evt void AutoCSelection=2022(string text)
+evt void AutoCSelection=2022(string text, int position)
evt void IndicatorClick=2023(int modifiers, int position)
evt void IndicatorRelease=2024(int modifiers, int position)
evt void AutoCCancelled=2025(void)
evt void AutoCCharDeleted=2026(void)
+evt void HotSpotReleaseClick=2027(int modifiers, int position)
+
+cat Deprecated
+
+# Deprecated in 2.21
+# The SC_CP_DBCS value can be used to indicate a DBCS mode for GTK+.
+val SC_CP_DBCS=1
diff --git a/plugins/scintilla/scintilla/include/ScintillaWidget.h b/plugins/scintilla/scintilla/include/ScintillaWidget.h
index eccc983..d1df6cf 100644
--- a/plugins/scintilla/scintilla/include/ScintillaWidget.h
+++ b/plugins/scintilla/scintilla/include/ScintillaWidget.h
@@ -9,14 +9,14 @@
#ifndef SCINTILLAWIDGET_H
#define SCINTILLAWIDGET_H
-#if PLAT_GTK
+#if defined(GTK)
#ifdef __cplusplus
extern "C" {
#endif
#define SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, scintilla_get_type (), ScintillaObject)
-#define SCINTILLA_CLASS(klass) G_TYPE_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass)
+#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass)
#define IS_SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_TYPE (obj, scintilla_get_type ())
typedef struct _ScintillaObject ScintillaObject;
@@ -34,21 +34,13 @@ struct _ScintillaClass {
void (* notify) (ScintillaObject *ttt);
};
-#if GLIB_MAJOR_VERSION < 2
-GtkType scintilla_get_type (void);
-#else
GType scintilla_get_type (void);
-#endif
GtkWidget* scintilla_new (void);
void scintilla_set_id (ScintillaObject *sci, uptr_t id);
sptr_t scintilla_send_message (ScintillaObject *sci,unsigned int iMessage, uptr_t wParam, sptr_t lParam);
void scintilla_release_resources(void);
-#if GTK_MAJOR_VERSION < 2
-#define SCINTILLA_NOTIFY "notify"
-#else
#define SCINTILLA_NOTIFY "sci-notify"
-#endif
#ifdef __cplusplus
}
diff --git a/plugins/scintilla/scintilla/lexers.make b/plugins/scintilla/scintilla/lexers.make
index ddebba0..fa32e55 100644
--- a/plugins/scintilla/scintilla/lexers.make
+++ b/plugins/scintilla/scintilla/lexers.make
@@ -1,6 +1,7 @@
## Lexers make file
LEXER_OBJS = \
StyleContext.o\
+ LexA68k.o\
LexAbaqus.o\
LexAda.o\
LexAPDL.o\
@@ -24,7 +25,11 @@ LEXER_OBJS = \
LexCSS.o\
LexD.o\
LexEiffel.o\
+ LexerBase.o\
LexErlang.o\
+ LexerModule.o\
+ LexerNoExceptions.o\
+ LexerSimple.o\
LexEScript.o\
LexFlagship.o\
LexForth.o\
@@ -43,6 +48,7 @@ LEXER_OBJS = \
LexMatlab.o\
LexMetapost.o\
LexMMIXAL.o\
+ LexModula.o\
LexMPT.o\
LexMSSQL.o\
LexMySQL.o\
@@ -75,12 +81,14 @@ LEXER_OBJS = \
LexTAL.o\
LexTCL.o\
LexTeX.o\
+ LexTxt2tags.o\
LexVB.o\
LexVerilog.o\
LexVHDL.o\
LexYAML.o
LEXER_SRCS = \
+ LexA68k.cxx\
LexAbaqus.cxx\
LexAda.cxx\
LexAPDL.cxx\
@@ -104,7 +112,11 @@ LEXER_SRCS = \
LexCSS.cxx\
LexD.cxx\
LexEiffel.cxx\
+ LexerBase.cxx\
LexErlang.cxx\
+ LexerModule.cxx\
+ LexerNoExceptions.cxx\
+ LexerSimple.cxx\
LexEScript.cxx\
LexFlagship.cxx\
LexForth.cxx\
@@ -123,6 +135,7 @@ LEXER_SRCS = \
LexMatlab.cxx\
LexMetapost.cxx\
LexMMIXAL.cxx\
+ LexModula.cxx\
LexMPT.cxx\
LexMSSQL.cxx\
LexMySQL.cxx\
@@ -155,6 +168,7 @@ LEXER_SRCS = \
LexTAL.cxx\
LexTCL.cxx\
LexTeX.cxx\
+ LexTxt2tags.cxx\
LexVB.cxx\
LexVerilog.cxx\
LexVHDL.cxx\
diff --git a/plugins/scintilla/scintilla/test-scintilla.cxx b/plugins/scintilla/scintilla/test-scintilla.cxx
index c4cdd4a..e27b62d 100644
--- a/plugins/scintilla/scintilla/test-scintilla.cxx
+++ b/plugins/scintilla/scintilla/test-scintilla.cxx
@@ -8,6 +8,40 @@
#include <Scintilla.h>
#include <ScintillaWidget.h>
+
+static int IntFromHexDigit(int ch) {
+ if ((ch >= '0') && (ch <= '9')) {
+ return ch - '0';
+ } else if (ch >= 'A' && ch <= 'F') {
+ return ch - 'A' + 10;
+ } else if (ch >= 'a' && ch <= 'f') {
+ return ch - 'a' + 10;
+ } else {
+ return 0;
+ }
+}
+
+static int IntFromHexByte(const char *hexByte) {
+ return IntFromHexDigit(hexByte[0]) * 16 + IntFromHexDigit(hexByte[1]);
+}
+
+typedef long Colour;
+Colour ColourRGB(unsigned int red, unsigned int green, unsigned int blue)
+{
+ return red | (green << 8) | (blue << 16);
+}
+
+static Colour ColourFromString(const char *s) {
+ if ((s != NULL) && (*s != '\0')) {
+ int r = IntFromHexByte(s + 1);
+ int g = IntFromHexByte(s + 3);
+ int b = IntFromHexByte(s + 5);
+ return ColourRGB(r, g, b);
+ } else {
+ return 0;
+ }
+}
+
void SetOneStyle(GtkWidget *sci, int style, const char *s) {
char *val = strdup(s);
char *opt = val;
@@ -29,11 +63,11 @@ void SetOneStyle(GtkWidget *sci, int style, const char *s) {
if (0 == strcmp(opt, "font"))
scintilla_send_message(SCINTILLA(sci), SCI_STYLESETFONT, style, reinterpret_cast<long>(colon));
if (0 == strcmp(opt, "fore"))
- //scintilla_send_message(SCINTILLA(sci), SCI_STYLESETFORE, style, ColourFromString(colon).AsLong());
+ scintilla_send_message(SCINTILLA(sci), SCI_STYLESETFORE, style, ColourFromString(colon));
if (0 == strcmp(opt, "back"))
- //scintilla_send_message(SCINTILLA(sci), SCI_STYLESETBACK, style, ColourFromString(colon).AsLong());
+ scintilla_send_message(SCINTILLA(sci), SCI_STYLESETBACK, style, ColourFromString(colon));
if (0 == strcmp(opt, "size"))
- scintilla_send_message(SCINTILLA(sci), SCI_STYLESETSIZE, style, atoi(colon));
+ scintilla_send_message(SCINTILLA(sci), SCI_STYLESETSIZE, style, atoi(colon));
if (0 == strcmp(opt, "eolfilled"))
scintilla_send_message(SCINTILLA(sci), SCI_STYLESETEOLFILLED, style, 1);
if (0 == strcmp(opt, "noteolfilled"))
@@ -91,7 +125,7 @@ int main(int argc, char **argv)
scintilla_send_message(SCINTILLA(sci), SCI_SETHSCROLLBAR, 0, 0);
scintilla_send_message(SCINTILLA(sci), SCI_SETCODEPAGE, SC_CP_UTF8, 0);
scintilla_send_message(SCINTILLA(sci), SCI_SETMARGINWIDTHN, 0, 40);
- //scintilla_set_id(SCINTILLA(sci), 0);
+ scintilla_set_id(SCINTILLA(sci), 0);
gtk_container_add (GTK_CONTAINER(win), sci);
g_signal_connect (G_OBJECT (win), "delete-event",
G_CALLBACK (gtk_main_quit), NULL);
diff --git a/plugins/scintilla/style-editor.c b/plugins/scintilla/style-editor.c
index a64f8fa..ff54584 100644
--- a/plugins/scintilla/style-editor.c
+++ b/plugins/scintilla/style-editor.c
@@ -572,7 +572,7 @@ on_hilite_style_entry_changed (GtkComboBox * combobox, gpointer user_data)
g_return_if_fail (user_data);
p = user_data;
- style_item = gtk_combo_box_get_active_text (combobox);
+ style_item = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT (combobox));
if (!style_item || strlen (style_item) <= 0)
return;
if (p->priv->current_style)
@@ -917,7 +917,7 @@ create_style_editor_gui (StyleEditor * se)
{
if (hilite_style[i] == NULL)
break;
- gtk_combo_box_append_text (GTK_COMBO_BOX (se->priv->hilite_item_combobox), hilite_style[i]);
+ gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (se->priv->hilite_item_combobox), hilite_style[i]);
}
diff --git a/plugins/scintilla/text_editor_cbs.c b/plugins/scintilla/text_editor_cbs.c
index 07cbe48..f6ee56e 100644
--- a/plugins/scintilla/text_editor_cbs.c
+++ b/plugins/scintilla/text_editor_cbs.c
@@ -76,7 +76,7 @@ on_text_editor_text_keyrelease_event (GtkWidget * widget,
GdkEventKey * event,
gpointer user_data)
{
- if (event->keyval == GDK_BackSpace)
+ if (event->keyval == GDK_KEY_BackSpace)
{
TextEditor *te = user_data;
g_signal_emit_by_name(G_OBJECT(te), "backspace");
@@ -120,14 +120,15 @@ static void
scintilla_uri_dropped (TextEditor *te, const char *uri)
{
GtkWidget *parent;
- GtkSelectionData tmp;
-
- tmp.data = (guchar *) uri;
+ // FIXME: Not possible to create a selection data anymore
+ //GtkSelectionData tmp;
+
+ //tmp.data = (guchar *) uri;
parent = gtk_widget_get_toplevel (GTK_WIDGET (te));
- if (parent)
- g_signal_emit_by_name (G_OBJECT (parent), "drag_data_received",
- NULL, 0, 0, &tmp, 0, 0);
+ //if (parent)
+ // g_signal_emit_by_name (G_OBJECT (parent), "drag_data_received",
+ // NULL, 0, 0, &tmp, 0, 0);
return;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]