Skip to content
Browse files

Update Scintilla to version 3.2.3

Closes #2909124, #3094431 and #3233160.
  • Loading branch information...
1 parent d7e285d commit 4d1675426779de628bc47bee3591df76a8028435 @b4n b4n committed Oct 25, 2012
View
4 scintilla/gtk/ScintillaGTK.cxx
@@ -1213,6 +1213,10 @@ bool ScintillaGTK::ModifyScrollBars(int nMax, int nPage) {
modified = true;
}
#endif
+ if (modified && (paintState == painting)) {
+ paintState = paintAbandoned;
+ }
+
return modified;
}
View
7 scintilla/include/SciLexer.h
@@ -1354,6 +1354,13 @@
#define SCE_PO_MSGCTXT 6
#define SCE_PO_MSGCTXT_TEXT 7
#define SCE_PO_FUZZY 8
+#define SCE_PO_PROGRAMMER_COMMENT 9
+#define SCE_PO_REFERENCE 10
+#define SCE_PO_FLAGS 11
+#define SCE_PO_MSGID_TEXT_EOL 12
+#define SCE_PO_MSGSTR_TEXT_EOL 13
+#define SCE_PO_MSGCTXT_TEXT_EOL 14
+#define SCE_PO_ERROR 15
#define SCE_PAS_DEFAULT 0
#define SCE_PAS_IDENTIFIER 1
#define SCE_PAS_COMMENT 2
View
7 scintilla/include/Scintilla.iface
@@ -3924,6 +3924,13 @@ val SCE_PO_MSGSTR_TEXT=5
val SCE_PO_MSGCTXT=6
val SCE_PO_MSGCTXT_TEXT=7
val SCE_PO_FUZZY=8
+val SCE_PO_PROGRAMMER_COMMENT=9
+val SCE_PO_REFERENCE=10
+val SCE_PO_FLAGS=11
+val SCE_PO_MSGID_TEXT_EOL=12
+val SCE_PO_MSGSTR_TEXT_EOL=13
+val SCE_PO_MSGCTXT_TEXT_EOL=14
+val SCE_PO_ERROR=15
# Lexical states for SCLEX_PASCAL
lex Pascal=SCLEX_PASCAL SCE_PAS_
val SCE_PAS_DEFAULT=0
View
4 scintilla/include/ScintillaWidget.h
@@ -16,8 +16,8 @@ extern "C" {
#endif
#define SCINTILLA(obj) G_TYPE_CHECK_INSTANCE_CAST (obj, scintilla_get_type (), ScintillaObject)
-#define SCINTILLA_CLASS(klass) GTK_CHECK_CLASS_CAST (klass, scintilla_get_type (), ScintillaClass)
-#define IS_SCINTILLA(obj) GTK_CHECK_TYPE (obj, scintilla_get_type ())
+#define SCINTILLA_CLASS(klass) G_TYPE_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;
typedef struct _ScintillaClass ScintillaClass;
View
156 scintilla/lexers/LexBash.cxx
@@ -2,7 +2,7 @@
/** @file LexBash.cxx
** Lexer for Bash.
**/
-// Copyright 2004-2010 by Neil Hodgson <neilh@scintilla.org>
+// Copyright 2004-2012 by Neil Hodgson <neilh@scintilla.org>
// Adapted from LexPerl by Kein-Hong Man 2004
// The License.txt file describes the conditions under which this software may be distributed.
@@ -49,6 +49,17 @@ using namespace Scintilla;
#define BASH_CMD_ARITH 4
#define BASH_CMD_DELIM 5
+// state constants for nested delimiter pairs, used by
+// SCE_SH_STRING and SCE_SH_BACKTICKS processing
+#define BASH_DELIM_LITERAL 0
+#define BASH_DELIM_STRING 1
+#define BASH_DELIM_CSTRING 2
+#define BASH_DELIM_LSTRING 3
+#define BASH_DELIM_COMMAND 4
+#define BASH_DELIM_BACKTICK 5
+
+#define BASH_DELIM_STACK_MAX 7
+
static inline int translateBashDigit(int ch) {
if (ch >= '0' && ch <= '9') {
return ch - '0';
@@ -154,6 +165,60 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
};
QuoteCls Quote;
+ class QuoteStackCls { // Class to manage quote pairs that nest
+ public:
+ int Count;
+ int Up, Down;
+ int Style;
+ int Depth; // levels pushed
+ int *CountStack;
+ int *UpStack;
+ int *StyleStack;
+ QuoteStackCls() {
+ Count = 0;
+ Up = '\0';
+ Down = '\0';
+ Style = 0;
+ Depth = 0;
+ CountStack = new int[BASH_DELIM_STACK_MAX];
+ UpStack = new int[BASH_DELIM_STACK_MAX];
+ StyleStack = new int[BASH_DELIM_STACK_MAX];
+ }
+ void Start(int u, int s) {
+ Count = 1;
+ Up = u;
+ Down = opposite(Up);
+ Style = s;
+ }
+ void Push(int u, int s) {
+ if (Depth >= BASH_DELIM_STACK_MAX)
+ return;
+ CountStack[Depth] = Count;
+ UpStack [Depth] = Up;
+ StyleStack[Depth] = Style;
+ Depth++;
+ Count = 1;
+ Up = u;
+ Down = opposite(Up);
+ Style = s;
+ }
+ void Pop(void) {
+ if (Depth <= 0)
+ return;
+ Depth--;
+ Count = CountStack[Depth];
+ Up = UpStack [Depth];
+ Style = StyleStack[Depth];
+ Down = opposite(Up);
+ }
+ ~QuoteStackCls() {
+ delete []CountStack;
+ delete []UpStack;
+ delete []StyleStack;
+ }
+ };
+ QuoteStackCls QuoteStack;
+
int numBase = 0;
int digit;
unsigned int endPos = startPos + length;
@@ -163,6 +228,8 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
// Always backtracks to the start of a line that is not a continuation
// of the previous line (i.e. start of a bash command segment)
int ln = styler.GetLine(startPos);
+ if (ln > 0 && startPos == static_cast<unsigned int>(styler.LineStart(ln)))
+ ln--;
for (;;) {
startPos = styler.LineStart(ln);
if (ln == 0 || styler.GetLineState(ln) == BASH_CMD_START)
@@ -376,7 +443,7 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.ForwardSetState(SCE_SH_DEFAULT);
} else if (sc.ch == '\\') {
// skip escape prefix
- } else {
+ } else if (!HereDoc.Quoted) {
sc.SetState(SCE_SH_DEFAULT);
}
if (HereDoc.DelimiterLength >= HERE_DELIM_MAX - 1) { // force blowup
@@ -401,8 +468,11 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
}
char s[HERE_DELIM_MAX];
sc.GetCurrent(s, sizeof(s));
- if (sc.LengthCurrent() == 0)
+ if (sc.LengthCurrent() == 0) { // '' or "" delimiters
+ if (prefixws == 0 && HereDoc.Quoted && HereDoc.DelimiterLength == 0)
+ sc.SetState(SCE_SH_DEFAULT);
break;
+ }
if (s[strlen(s) - 1] == '\r')
s[strlen(s) - 1] = '\0';
if (strcmp(HereDoc.Delimiter, s) == 0) {
@@ -424,9 +494,56 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
}
}
break;
- case SCE_SH_STRING: // delimited styles
+ case SCE_SH_STRING: // delimited styles, can nest
case SCE_SH_BACKTICKS:
- case SCE_SH_PARAM:
+ if (sc.ch == '\\' && QuoteStack.Up != '\\') {
+ if (QuoteStack.Style != BASH_DELIM_LITERAL)
+ sc.Forward();
+ } else if (sc.ch == QuoteStack.Down) {
+ QuoteStack.Count--;
+ if (QuoteStack.Count == 0) {
+ if (QuoteStack.Depth > 0) {
+ QuoteStack.Pop();
+ } else
+ sc.ForwardSetState(SCE_SH_DEFAULT);
+ }
+ } else if (sc.ch == QuoteStack.Up) {
+ QuoteStack.Count++;
+ } else {
+ if (QuoteStack.Style == BASH_DELIM_STRING ||
+ QuoteStack.Style == BASH_DELIM_LSTRING
+ ) { // do nesting for "string", $"locale-string"
+ if (sc.ch == '`') {
+ QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK);
+ } else if (sc.ch == '$' && sc.chNext == '(') {
+ sc.Forward();
+ QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND);
+ }
+ } else if (QuoteStack.Style == BASH_DELIM_COMMAND ||
+ QuoteStack.Style == BASH_DELIM_BACKTICK
+ ) { // do nesting for $(command), `command`
+ if (sc.ch == '\'') {
+ QuoteStack.Push(sc.ch, BASH_DELIM_LITERAL);
+ } else if (sc.ch == '\"') {
+ QuoteStack.Push(sc.ch, BASH_DELIM_STRING);
+ } else if (sc.ch == '`') {
+ QuoteStack.Push(sc.ch, BASH_DELIM_BACKTICK);
+ } else if (sc.ch == '$') {
+ if (sc.chNext == '\'') {
+ sc.Forward();
+ QuoteStack.Push(sc.ch, BASH_DELIM_CSTRING);
+ } else if (sc.chNext == '\"') {
+ sc.Forward();
+ QuoteStack.Push(sc.ch, BASH_DELIM_LSTRING);
+ } else if (sc.chNext == '(') {
+ sc.Forward();
+ QuoteStack.Push(sc.ch, BASH_DELIM_COMMAND);
+ }
+ }
+ }
+ }
+ break;
+ case SCE_SH_PARAM: // ${parameter}
if (sc.ch == '\\' && Quote.Up != '\\') {
sc.Forward();
} else if (sc.ch == Quote.Down) {
@@ -461,8 +578,14 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.ChangeState(SCE_SH_ERROR);
}
// HereDoc.Quote always == '\''
+ sc.SetState(SCE_SH_HERE_Q);
+ } else if (HereDoc.DelimiterLength == 0) {
+ // no delimiter, illegal (but '' and "" are legal)
+ sc.ChangeState(SCE_SH_ERROR);
+ sc.SetState(SCE_SH_DEFAULT);
+ } else {
+ sc.SetState(SCE_SH_HERE_Q);
}
- sc.SetState(SCE_SH_HERE_Q);
}
// update cmdState about the current command segment
@@ -497,13 +620,13 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_SH_COMMENTLINE);
} else if (sc.ch == '\"') {
sc.SetState(SCE_SH_STRING);
- Quote.Start(sc.ch);
+ QuoteStack.Start(sc.ch, BASH_DELIM_STRING);
} else if (sc.ch == '\'') {
sc.SetState(SCE_SH_CHARACTER);
Quote.Start(sc.ch);
} else if (sc.ch == '`') {
sc.SetState(SCE_SH_BACKTICKS);
- Quote.Start(sc.ch);
+ QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK);
} else if (sc.ch == '$') {
if (sc.Match("$((")) {
sc.SetState(SCE_SH_OPERATOR); // handle '((' later
@@ -513,17 +636,22 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
sc.Forward();
if (sc.ch == '{') {
sc.ChangeState(SCE_SH_PARAM);
+ Quote.Start(sc.ch);
} else if (sc.ch == '\'') {
sc.ChangeState(SCE_SH_STRING);
+ QuoteStack.Start(sc.ch, BASH_DELIM_CSTRING);
} else if (sc.ch == '"') {
sc.ChangeState(SCE_SH_STRING);
- } else if (sc.ch == '(' || sc.ch == '`') {
+ QuoteStack.Start(sc.ch, BASH_DELIM_LSTRING);
+ } else if (sc.ch == '(') {
+ sc.ChangeState(SCE_SH_BACKTICKS);
+ QuoteStack.Start(sc.ch, BASH_DELIM_COMMAND);
+ } else if (sc.ch == '`') { // $` seen in a configure script, valid?
sc.ChangeState(SCE_SH_BACKTICKS);
+ QuoteStack.Start(sc.ch, BASH_DELIM_BACKTICK);
} else {
continue; // scalar has no delimiter pair
}
- // fallthrough, open delim for $[{'"(`]
- Quote.Start(sc.ch);
} else if (sc.Match('<', '<')) {
sc.SetState(SCE_SH_HERE_DELIM);
HereDoc.State = 0;
@@ -597,6 +725,10 @@ static void ColouriseBashDoc(unsigned int startPos, int length, int initStyle,
}// sc.state
}
sc.Complete();
+ if (sc.state == SCE_SH_HERE_Q) {
+ styler.ChangeLexerState(sc.currentPos, styler.Length());
+ }
+ sc.Complete();
}
static bool IsCommentLine(int line, Accessor &styler) {
@@ -651,7 +783,7 @@ static void FoldBashDoc(unsigned int startPos, int length, int, WordList *[],
if (ch == '<' && chNext == '<') {
levelCurrent++;
}
- } else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_PL_DEFAULT) {
+ } else if (style == SCE_SH_HERE_Q && styler.StyleAt(i+1) == SCE_SH_DEFAULT) {
levelCurrent--;
}
if (atEOL) {
View
15 scintilla/lexers/LexCPP.cxx
@@ -467,6 +467,7 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
int styleBeforeDCKeyword = SCE_C_DEFAULT;
bool continuationLine = false;
bool isIncludePreprocessor = false;
+ bool isStringInPreprocessor = false;
int lineCurrent = styler.GetLine(startPos);
if ((MaskActive(initStyle) == SCE_C_PREPROCESSOR) ||
@@ -578,7 +579,9 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
break;
case SCE_C_NUMBER:
// We accept almost anything because of hex. and number suffixes
- if (!(setWord.Contains(sc.ch) || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E')))) {
+ if (!(setWord.Contains(sc.ch)
+ || ((sc.ch == '+' || sc.ch == '-') && (sc.chPrev == 'e' || sc.chPrev == 'E' ||
+ sc.chPrev == 'p' || sc.chPrev == 'P')))) {
sc.SetState(SCE_C_DEFAULT|activitySet);
}
break;
@@ -618,13 +621,17 @@ void SCI_METHOD LexerCPP::Lex(unsigned int startPos, int length, int initStyle,
sc.SetState(SCE_C_DEFAULT|activitySet);
}
break;
- case SCE_C_PREPROCESSOR:
+ case SCE_C_PREPROCESSOR:
if (options.stylingWithinPreprocessor) {
if (IsASpace(sc.ch)) {
sc.SetState(SCE_C_DEFAULT|activitySet);
}
- } else {
- if (sc.Match('/', '*')) {
+ } else if (isStringInPreprocessor && (sc.Match('>') || sc.Match('\"'))) {
+ isStringInPreprocessor = false;
+ } else if (!isStringInPreprocessor) {
+ if ((isIncludePreprocessor && sc.Match('<')) || sc.Match('\"')) {
+ isStringInPreprocessor = true;
+ } else if (sc.Match('/', '*')) {
sc.SetState(SCE_C_PREPROCESSORCOMMENT|activitySet);
sc.Forward(); // Eat the *
} else if (sc.Match('/', '/')) {
View
73 scintilla/lexers/LexOthers.cxx
@@ -614,78 +614,6 @@ static void FoldDiffDoc(unsigned int startPos, int length, int, WordList *[], Ac
} while (static_cast<int>(startPos) + length > curLineStart);
}
-static void ColourisePoLine(
- char *lineBuffer,
- unsigned int lengthLine,
- unsigned int startLine,
- unsigned int endPos,
- Accessor &styler) {
-
- unsigned int i = 0;
- static unsigned int state = SCE_PO_DEFAULT;
- unsigned int state_start = SCE_PO_DEFAULT;
-
- while ((i < lengthLine) && isspacechar(lineBuffer[i])) // Skip initial spaces
- i++;
- if (i < lengthLine) {
- if (lineBuffer[i] == '#') {
- // check if the comment contains any flags ("#, ") and
- // then whether the flags contain "fuzzy"
- if (strstart(lineBuffer, "#, ") && strstr(lineBuffer, "fuzzy"))
- styler.ColourTo(endPos, SCE_PO_FUZZY);
- else
- styler.ColourTo(endPos, SCE_PO_COMMENT);
- } else {
- if (lineBuffer[0] == '"') {
- // line continuation, use previous style
- styler.ColourTo(endPos, state);
- return;
- // this implicitly also matches "msgid_plural"
- } else if (strstart(lineBuffer, "msgid")) {
- state_start = SCE_PO_MSGID;
- state = SCE_PO_MSGID_TEXT;
- } else if (strstart(lineBuffer, "msgstr")) {
- state_start = SCE_PO_MSGSTR;
- state = SCE_PO_MSGSTR_TEXT;
- } else if (strstart(lineBuffer, "msgctxt")) {
- state_start = SCE_PO_MSGCTXT;
- state = SCE_PO_MSGCTXT_TEXT;
- }
- if (state_start != SCE_PO_DEFAULT) {
- // find the next space
- while ((i < lengthLine) && ! isspacechar(lineBuffer[i]))
- i++;
- styler.ColourTo(startLine + i - 1, state_start);
- styler.ColourTo(startLine + i, SCE_PO_DEFAULT);
- styler.ColourTo(endPos, state);
- }
- }
- } else {
- styler.ColourTo(endPos, SCE_PO_DEFAULT);
- }
-}
-
-static void ColourisePoDoc(unsigned int startPos, int length, int, WordList *[], Accessor &styler) {
- char lineBuffer[1024];
- styler.StartAt(startPos);
- styler.StartSegment(startPos);
- unsigned int linePos = 0;
- unsigned int startLine = startPos;
- for (unsigned int i = startPos; i < startPos + length; i++) {
- lineBuffer[linePos++] = styler[i];
- if (AtEOL(styler, i) || (linePos >= sizeof(lineBuffer) - 1)) {
- // End of line (or of line buffer) met, colourise it
- lineBuffer[linePos] = '\0';
- ColourisePoLine(lineBuffer, linePos, startLine, i, styler);
- linePos = 0;
- startLine = i + 1;
- }
- }
- if (linePos > 0) { // Last line does not have ending characters
- ColourisePoLine(lineBuffer, linePos, startLine, startPos + length - 1, styler);
- }
-}
-
static inline bool isassignchar(unsigned char ch) {
return (ch == '=') || (ch == ':');
}
@@ -1498,7 +1426,6 @@ static void ColouriseNullDoc(unsigned int startPos, int length, int, WordList *[
LexerModule lmBatch(SCLEX_BATCH, ColouriseBatchDoc, "batch", 0, batchWordListDesc);
LexerModule lmDiff(SCLEX_DIFF, ColouriseDiffDoc, "diff", FoldDiffDoc, emptyWordListDesc);
-LexerModule lmPo(SCLEX_PO, ColourisePoDoc, "po", 0, emptyWordListDesc);
LexerModule lmProps(SCLEX_PROPERTIES, ColourisePropsDoc, "props", FoldPropsDoc, emptyWordListDesc);
LexerModule lmMake(SCLEX_MAKEFILE, ColouriseMakeDoc, "makefile", 0, emptyWordListDesc);
LexerModule lmErrorList(SCLEX_ERRORLIST, ColouriseErrorListDoc, "errorlist", 0, emptyWordListDesc);
View
149 scintilla/lexers/LexPO.cxx
@@ -0,0 +1,149 @@
+// Scintilla source code edit control
+/** @file LexPO.cxx
+ ** Lexer for GetText Translation (PO) files.
+ **/
+// Copyright 2012 by Colomban Wendling <ban@herbesfolles.org>
+// The License.txt file describes the conditions under which this software may be distributed.
+
+// see https://www.gnu.org/software/gettext/manual/gettext.html#PO-Files for the syntax reference
+// some details are taken from the GNU msgfmt behavior (like that indent is allows in front of lines)
+
+// TODO:
+// * add keywords for flags (fuzzy, c-format, ...)
+// * highlight formats inside c-format strings (%s, %d, etc.)
+// * style for previous untranslated string? ("#|" comment)
+
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <assert.h>
+#include <ctype.h>
+
+#include "ILexer.h"
+#include "Scintilla.h"
+#include "SciLexer.h"
+
+#include "WordList.h"
+#include "LexAccessor.h"
+#include "Accessor.h"
+#include "StyleContext.h"
+#include "CharacterSet.h"
+#include "LexerModule.h"
+
+#ifdef SCI_NAMESPACE
+using namespace Scintilla;
+#endif
+
+static void ColourisePODoc(unsigned int startPos, int length, int initStyle, WordList *[], Accessor &styler) {
+ StyleContext sc(startPos, length, initStyle, styler);
+ bool escaped = false;
+ int curLine = styler.GetLine(startPos);
+ // the line state holds the last state on or before the line that isn't the default style
+ int curLineState = curLine > 0 ? styler.GetLineState(curLine - 1) : SCE_PO_DEFAULT;
+
+ for (; sc.More(); sc.Forward()) {
+ // whether we should leave a state
+ switch (sc.state) {
+ case SCE_PO_COMMENT:
+ case SCE_PO_PROGRAMMER_COMMENT:
+ case SCE_PO_REFERENCE:
+ case SCE_PO_FLAGS:
+ case SCE_PO_FUZZY:
+ if (sc.atLineEnd)
+ sc.SetState(SCE_PO_DEFAULT);
+ else if (sc.state == SCE_PO_FLAGS && sc.Match("fuzzy"))
+ // here we behave like the previous parser, but this should probably be highlighted
+ // on its own like a keyword rather than changing the whole flags style
+ sc.ChangeState(SCE_PO_FUZZY);
+ break;
+
+ case SCE_PO_MSGCTXT:
+ case SCE_PO_MSGID:
+ case SCE_PO_MSGSTR:
+ if (isspacechar(sc.ch))
+ sc.SetState(SCE_PO_DEFAULT);
+ break;
+
+ case SCE_PO_ERROR:
+ if (sc.atLineEnd)
+ sc.SetState(SCE_PO_DEFAULT);
+ break;
+
+ case SCE_PO_MSGCTXT_TEXT:
+ case SCE_PO_MSGID_TEXT:
+ case SCE_PO_MSGSTR_TEXT:
+ if (sc.atLineEnd) { // invalid inside a string
+ if (sc.state == SCE_PO_MSGCTXT_TEXT)
+ sc.ChangeState(SCE_PO_MSGCTXT_TEXT_EOL);
+ else if (sc.state == SCE_PO_MSGID_TEXT)
+ sc.ChangeState(SCE_PO_MSGID_TEXT_EOL);
+ else if (sc.state == SCE_PO_MSGSTR_TEXT)
+ sc.ChangeState(SCE_PO_MSGSTR_TEXT_EOL);
+ sc.SetState(SCE_PO_DEFAULT);
+ escaped = false;
+ } else {
+ if (escaped)
+ escaped = false;
+ else if (sc.ch == '\\')
+ escaped = true;
+ else if (sc.ch == '"')
+ sc.ForwardSetState(SCE_PO_DEFAULT);
+ }
+ break;
+ }
+
+ // whether we should enter a new state
+ if (sc.state == SCE_PO_DEFAULT) {
+ // forward to the first non-white character on the line
+ bool atLineStart = sc.atLineStart;
+ if (atLineStart) {
+ while (sc.More() && ! sc.atLineEnd && isspacechar(sc.ch))
+ sc.Forward();
+ }
+
+ if (atLineStart && sc.ch == '#') {
+ if (sc.chNext == '.')
+ sc.SetState(SCE_PO_PROGRAMMER_COMMENT);
+ else if (sc.chNext == ':')
+ sc.SetState(SCE_PO_REFERENCE);
+ else if (sc.chNext == ',')
+ sc.SetState(SCE_PO_FLAGS);
+ else
+ sc.SetState(SCE_PO_COMMENT);
+ } else if (atLineStart && sc.Match("msgid")) { // includes msgid_plural
+ sc.SetState(SCE_PO_MSGID);
+ } else if (atLineStart && sc.Match("msgstr")) { // includes [] suffixes
+ sc.SetState(SCE_PO_MSGSTR);
+ } else if (atLineStart && sc.Match("msgctxt")) {
+ sc.SetState(SCE_PO_MSGCTXT);
+ } else if (sc.ch == '"') {
+ if (curLineState == SCE_PO_MSGCTXT || curLineState == SCE_PO_MSGCTXT_TEXT)
+ sc.SetState(SCE_PO_MSGCTXT_TEXT);
+ else if (curLineState == SCE_PO_MSGID || curLineState == SCE_PO_MSGID_TEXT)
+ sc.SetState(SCE_PO_MSGID_TEXT);
+ else if (curLineState == SCE_PO_MSGSTR || curLineState == SCE_PO_MSGSTR_TEXT)
+ sc.SetState(SCE_PO_MSGSTR_TEXT);
+ else
+ sc.SetState(SCE_PO_ERROR);
+ } else if (! isspacechar(sc.ch))
+ sc.SetState(SCE_PO_ERROR);
+
+ if (sc.state != SCE_PO_DEFAULT)
+ curLineState = sc.state;
+ }
+
+ if (sc.atLineEnd) {
+ // Update the line state, so it can be seen by next line
+ curLine = styler.GetLine(sc.currentPos);
+ styler.SetLineState(curLine, curLineState);
+ }
+ }
+ sc.Complete();
+}
+
+static const char *const poWordListDesc[] = {
+ 0
+};
+
+LexerModule lmPO(SCLEX_PO, ColourisePODoc, "po", 0, poWordListDesc);
View
14 scintilla/lexers/LexRuby.cxx
@@ -465,7 +465,9 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
}
prevStyle = styler.StyleAt(firstWordPosn);
// If we have '<<' following a keyword, it's not a heredoc
- if (prevStyle != SCE_RB_IDENTIFIER) {
+ if (prevStyle != SCE_RB_IDENTIFIER
+ && prevStyle != SCE_RB_INSTANCE_VAR
+ && prevStyle != SCE_RB_CLASS_VAR) {
return definitely_not_a_here_doc;
}
int newStyle = prevStyle;
@@ -495,6 +497,9 @@ static bool sureThisIsNotHeredoc(int lt2StartPos,
} else {
break;
}
+ // on second and next passes, only identifiers may appear since
+ // class and instance variable are private
+ prevStyle = SCE_RB_IDENTIFIER;
}
// Skip next batch of white-space
firstWordPosn = skipWhitespace(firstWordPosn, lt2StartPos, styler);
@@ -1436,7 +1441,8 @@ static bool keywordIsAmbiguous(const char *prevWord)
|| !strcmp(prevWord, "do")
|| !strcmp(prevWord, "while")
|| !strcmp(prevWord, "unless")
- || !strcmp(prevWord, "until")) {
+ || !strcmp(prevWord, "until")
+ || !strcmp(prevWord, "for")) {
return true;
} else {
return false;
@@ -1554,6 +1560,7 @@ static bool keywordIsModifier(const char *word,
#define WHILE_BACKWARDS "elihw"
#define UNTIL_BACKWARDS "litnu"
+#define FOR_BACKWARDS "rof"
// Nothing fancy -- look to see if we follow a while/until somewhere
// on the current line
@@ -1591,7 +1598,8 @@ static bool keywordDoStartsLoop(int pos,
*dst = 0;
// Did we see our keyword?
if (!strcmp(prevWord, WHILE_BACKWARDS)
- || !strcmp(prevWord, UNTIL_BACKWARDS)) {
+ || !strcmp(prevWord, UNTIL_BACKWARDS)
+ || !strcmp(prevWord, FOR_BACKWARDS)) {
return true;
}
// We can move pos to the beginning of the keyword, and then
View
33 scintilla/lexers/LexSQL.cxx
@@ -122,13 +122,11 @@ public :
return sqlStatesLine;
}
-
- unsigned short int IntoSelectStatement (unsigned short int sqlStatesLine, bool found) {
+ unsigned short int IntoSelectStatementOrAssignment (unsigned short int sqlStatesLine, bool found) {
if (found)
- sqlStatesLine |= MASK_INTO_SELECT_STATEMENT;
+ sqlStatesLine |= MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT;
else
- sqlStatesLine &= ~MASK_INTO_SELECT_STATEMENT;
-
+ sqlStatesLine &= ~MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT;
return sqlStatesLine;
}
@@ -161,11 +159,9 @@ public :
bool IsIntoExceptionBlock (unsigned short int sqlStatesLine) {
return (sqlStatesLine & MASK_INTO_EXCEPTION) != 0;
}
-
- bool IsIntoSelectStatement (unsigned short int sqlStatesLine) {
- return (sqlStatesLine & MASK_INTO_SELECT_STATEMENT) != 0;
+ bool IsIntoSelectStatementOrAssignment (unsigned short int sqlStatesLine) {
+ return (sqlStatesLine & MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT) != 0;
}
-
bool IsCaseMergeWithoutWhenFound (unsigned short int sqlStatesLine) {
return (sqlStatesLine & MASK_CASE_MERGE_WITHOUT_WHEN_FOUND) != 0;
}
@@ -188,7 +184,7 @@ private :
SparseState <unsigned short int> sqlStatement;
enum {
MASK_NESTED_CASES = 0x01FF,
- MASK_INTO_SELECT_STATEMENT = 0x0200,
+ MASK_INTO_SELECT_STATEMENT_OR_ASSIGNEMENT = 0x0200,
MASK_CASE_MERGE_WITHOUT_WHEN_FOUND = 0x0400,
MASK_MERGE_STATEMENT = 0x0800,
MASK_INTO_DECLARE = 0x1000,
@@ -608,9 +604,12 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
sqlStatesCurrentLine = sqlStates.IntoMergeStatement(sqlStatesCurrentLine, false);
levelNext--;
}
- if (sqlStates.IsIntoSelectStatement(sqlStatesCurrentLine))
- sqlStatesCurrentLine = sqlStates.IntoSelectStatement(sqlStatesCurrentLine, false);
+ if (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine))
+ sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, false);
}
+ if (ch == ':' && chNext == '=' && !IsCommentStyle(style))
+ sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true);
+
if (options.foldComment && IsStreamCommentStyle(style)) {
if (!IsStreamCommentStyle(stylePrev)) {
levelNext++;
@@ -666,10 +665,9 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
} else {
s[j] = '\0';
}
-
if (!options.foldOnlyBegin &&
strcmp(s, "select") == 0) {
- sqlStatesCurrentLine = sqlStates.IntoSelectStatement(sqlStatesCurrentLine, true);
+ sqlStatesCurrentLine = sqlStates.IntoSelectStatementOrAssignment(sqlStatesCurrentLine, true);
} else if (strcmp(s, "if") == 0) {
if (endFound) {
endFound = false;
@@ -719,16 +717,17 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
levelNext--; //again for the "end case;" and block when
}
} else if (!options.foldOnlyBegin) {
- if (strcmp(s, "case") == 0)
+ if (strcmp(s, "case") == 0) {
sqlStatesCurrentLine = sqlStates.BeginCaseBlock(sqlStatesCurrentLine);
+ sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
+ }
if (levelCurrent > levelNext)
levelCurrent = levelNext;
if (!statementFound)
levelNext++;
- sqlStatesCurrentLine = sqlStates.CaseMergeWithoutWhenFound(sqlStatesCurrentLine, true);
statementFound = true;
} else if (levelCurrent > levelNext) {
// doesn't include this line into the folding block
@@ -765,7 +764,7 @@ void SCI_METHOD LexerSQL::Fold(unsigned int startPos, int length, int initStyle,
(strcmp(s, "endif") == 0)) {
endFound = true;
levelNext--;
- if (sqlStates.IsIntoSelectStatement(sqlStatesCurrentLine) && !sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
+ if (sqlStates.IsIntoSelectStatementOrAssignment(sqlStatesCurrentLine) && !sqlStates.IsCaseMergeWithoutWhenFound(sqlStatesCurrentLine))
levelNext--;
if (levelNext < SC_FOLDLEVELBASE) {
levelNext = SC_FOLDLEVELBASE;
View
2 scintilla/src/Catalogue.cxx
@@ -109,7 +109,7 @@ int Scintilla_LinkLexers() {
LINK_LEXER(lmOctave);
LINK_LEXER(lmPascal);
LINK_LEXER(lmPerl);
- LINK_LEXER(lmPo);
+ LINK_LEXER(lmPO);
LINK_LEXER(lmProps);
LINK_LEXER(lmPython);
LINK_LEXER(lmR);
View
24 scintilla/src/Document.cxx
@@ -69,6 +69,7 @@ void LexInterface::Colourise(int start, int end) {
Document::Document() {
refCount = 0;
+ pcf = NULL;
#ifdef _WIN32
eolMode = SC_EOL_CRLF;
#else
@@ -123,6 +124,8 @@ Document::~Document() {
regex = 0;
delete pli;
pli = 0;
+ delete pcf;
+ pcf = 0;
}
void Document::Init() {
@@ -132,6 +135,16 @@ void Document::Init() {
}
}
+bool Document::SetDBCSCodePage(int dbcsCodePage_) {
+ if (dbcsCodePage != dbcsCodePage_) {
+ dbcsCodePage = dbcsCodePage_;
+ SetCaseFolder(NULL);
+ return true;
+ } else {
+ return false;
+ }
+}
+
void Document::InsertLine(int line) {
for (int j=0; j<ldSize; j++) {
if (perLineData[j])
@@ -1419,14 +1432,23 @@ bool Document::MatchesWordOptions(bool word, bool wordStart, int pos, int length
(wordStart && IsWordStartAt(pos));
}
+bool Document::HasCaseFolder(void) const {
+ return pcf != 0;
+}
+
+void Document::SetCaseFolder(CaseFolder *pcf_) {
+ delete pcf;
+ pcf = pcf_;
+}
+
/**
* Find text in document, supporting both forward and backward
* searches (just pass minPos > maxPos to do a backward search)
* Has not been tested with backwards DBCS searches yet.
*/
long Document::FindText(int minPos, int maxPos, const char *search,
bool caseSensitive, bool word, bool wordStart, bool regExp, int flags,
- int *length, CaseFolder *pcf) {
+ int *length) {
if (*length <= 0)
return minPos;
if (regExp) {
View
6 scintilla/src/Document.h
@@ -212,6 +212,7 @@ class Document : PerLine, public IDocument, public ILoader {
int refCount;
CellBuffer cb;
CharClassify charClass;
+ CaseFolder *pcf;
char stylingMask;
int endStyled;
int styleClock;
@@ -255,6 +256,7 @@ class Document : PerLine, public IDocument, public ILoader {
int SCI_METHOD Release();
virtual void Init();
+ bool SetDBCSCodePage(int dbcsCodePage_);
virtual void InsertLine(int line);
virtual void RemoveLine(int line);
@@ -355,8 +357,10 @@ class Document : PerLine, public IDocument, public ILoader {
int SCI_METHOD Length() const { return cb.Length(); }
void Allocate(int newSize) { cb.Allocate(newSize); }
bool MatchesWordOptions(bool word, bool wordStart, int pos, int length);
+ bool HasCaseFolder(void) const;
+ void SetCaseFolder(CaseFolder *pcf_);
long FindText(int minPos, int maxPos, const char *search, bool caseSensitive, bool word,
- bool wordStart, bool regExp, int flags, int *length, CaseFolder *pcf);
+ bool wordStart, bool regExp, int flags, int *length);
const char *SubstituteByPosition(const char *text, int *length);
int LinesTotal() const;
View
45 scintilla/src/Editor.cxx
@@ -220,6 +220,7 @@ Editor::Editor() {
marginNumberPadding = 3;
ctrlCharPadding = 3; // +3 For a blank on front and rounded edge each side
+ lastSegItalicsOffset = 2;
hsStart = -1;
hsEnd = -1;
@@ -2243,7 +2244,7 @@ void Editor::LayoutLine(int line, Surface *surface, ViewStyle &vstyle, LineLayou
}
// Small hack to make lines that end with italics not cut off the edge of the last character
if ((startseg > 0) && lastSegItalics) {
- ll->positions[startseg] += 2;
+ ll->positions[startseg] += lastSegItalicsOffset;
}
ll->numCharsInLine = numCharsInLine;
ll->numCharsBeforeEOL = numCharsBeforeEOL;
@@ -3438,6 +3439,8 @@ void Editor::Paint(Surface *surfaceWindow, PRectangle rcArea) {
AllocateGraphics();
RefreshStyleData();
+ if (paintState == paintAbandoned)
+ return; // Scroll bars may have changed so need redraw
RefreshPixMaps(surfaceWindow);
StyleToPositionInView(PositionAfterArea(rcArea));
@@ -5732,15 +5735,15 @@ long Editor::FindText(
Sci_TextToFind *ft = reinterpret_cast<Sci_TextToFind *>(lParam);
int lengthFound = istrlen(ft->lpstrText);
- std::auto_ptr<CaseFolder> pcf(CaseFolderForEncoding());
+ if (!pdoc->HasCaseFolder())
+ pdoc->SetCaseFolder(CaseFolderForEncoding());
int pos = pdoc->FindText(ft->chrg.cpMin, ft->chrg.cpMax, ft->lpstrText,
(wParam & SCFIND_MATCHCASE) != 0,
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound,
- pcf.get());
+ &lengthFound);
if (pos != -1) {
ft->chrgText.cpMin = pos;
ft->chrgText.cpMax = pos + lengthFound;
@@ -5763,19 +5766,6 @@ void Editor::SearchAnchor() {
searchAnchor = SelectionStart().Position();
}
-// Simple RAII wrapper for CaseFolder as std::auto_ptr is now deprecated
-class ScopedCaseFolder {
- CaseFolder *pcf;
-public:
- ScopedCaseFolder(CaseFolder *pcf_) : pcf(pcf_) {
- }
- ~ScopedCaseFolder() {
- delete pcf;
- pcf = 0;
- }
- CaseFolder *get() const { return pcf; }
-};
-
/**
* Find text from current search anchor: Must call @c SearchAnchor first.
* Used for next text and previous text requests.
@@ -5790,25 +5780,24 @@ long Editor::SearchText(
const char *txt = reinterpret_cast<char *>(lParam);
int pos;
int lengthFound = istrlen(txt);
- ScopedCaseFolder pcf(CaseFolderForEncoding());
+ if (!pdoc->HasCaseFolder())
+ pdoc->SetCaseFolder(CaseFolderForEncoding());
if (iMessage == SCI_SEARCHNEXT) {
pos = pdoc->FindText(searchAnchor, pdoc->Length(), txt,
(wParam & SCFIND_MATCHCASE) != 0,
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound,
- pcf.get());
+ &lengthFound);
} else {
pos = pdoc->FindText(searchAnchor, 0, txt,
(wParam & SCFIND_MATCHCASE) != 0,
(wParam & SCFIND_WHOLEWORD) != 0,
(wParam & SCFIND_WORDSTART) != 0,
(wParam & SCFIND_REGEXP) != 0,
wParam,
- &lengthFound,
- pcf.get());
+ &lengthFound);
}
if (pos != -1) {
SetSelection(pos, pos + lengthFound);
@@ -5841,15 +5830,15 @@ std::string Editor::CaseMapString(const std::string &s, int caseMapping) {
long Editor::SearchInTarget(const char *text, int length) {
int lengthFound = length;
- ScopedCaseFolder pcf(CaseFolderForEncoding());
+ if (!pdoc->HasCaseFolder())
+ pdoc->SetCaseFolder(CaseFolderForEncoding());
int pos = pdoc->FindText(targetStart, targetEnd, text,
(searchFlags & SCFIND_MATCHCASE) != 0,
(searchFlags & SCFIND_WHOLEWORD) != 0,
(searchFlags & SCFIND_WORDSTART) != 0,
(searchFlags & SCFIND_REGEXP) != 0,
searchFlags,
- &lengthFound,
- pcf.get());
+ &lengthFound);
if (pos != -1) {
targetStart = pos;
targetEnd = pos + lengthFound;
@@ -7098,6 +7087,7 @@ void Editor::StyleSetMessage(unsigned int iMessage, uptr_t wParam, sptr_t lParam
break;
case SCI_STYLESETCHARACTERSET:
vs.styles[wParam].characterSet = lParam;
+ pdoc->SetCaseFolder(NULL);
break;
case SCI_STYLESETVISIBLE:
vs.styles[wParam].visible = lParam != 0;
@@ -8076,8 +8066,9 @@ sptr_t Editor::WndProc(unsigned int iMessage, uptr_t wParam, sptr_t lParam) {
case SCI_SETCODEPAGE:
if (ValidCodePage(wParam)) {
- pdoc->dbcsCodePage = wParam;
- InvalidateStyleRedraw();
+ if (pdoc->SetDBCSCodePage(wParam)) {
+ InvalidateStyleRedraw();
+ }
}
break;
View
1 scintilla/src/Editor.h
@@ -271,6 +271,7 @@ class Editor : public DocWatcher {
int marginNumberPadding; // the right-side padding of the number margin
int ctrlCharPadding; // the padding around control character text blobs
+ int lastSegItalicsOffset; // the offset so as not to clip italic characters at EOLs
Document *pdoc;
View
2 scintilla/src/RESearch.cxx
@@ -788,7 +788,7 @@ int RESearch::Execute(CharacterIndexer &ci, int lp, int endp) {
}
case CHR: /* ordinary char: locate it fast */
c = *(ap+1);
- while ((lp < endp) && (ci.CharAt(lp) != c))
+ while ((lp < endp) && (static_cast<unsigned char>(ci.CharAt(lp)) != c))
lp++;
if (lp >= endp) /* if EOS, fail, else fall thru. */
return 0;
View
1 scintilla/src/RunStyles.cxx
@@ -205,6 +205,7 @@ void RunStyles::DeleteRange(int position, int deleteLength) {
if (runStart == runEnd) {
// Deleting from inside one run
starts->InsertText(runStart, -deleteLength);
+ RemoveRunIfEmpty(runStart);
} else {
runStart = SplitRun(position);
runEnd = SplitRun(end);
View
2 scintilla/version.txt
@@ -1 +1 @@
-322
+323

0 comments on commit 4d16754

Please sign in to comment.
Something went wrong with that request. Please try again.