aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorJohn Ehresman <unknown>2017-02-15 16:25:04 +1100
committerJohn Ehresman <unknown>2017-02-15 16:25:04 +1100
commit6f91daae77d449edac51aa1385e673c76b95792b (patch)
treeebc2ce0bb80e70697f7a2a69d916d5c5fe52ccb4
parentc0df83f637c42982662aaa802f691abb3d529a2e (diff)
downloadscintilla-mirror-6f91daae77d449edac51aa1385e673c76b95792b.tar.gz
Bug [#1848]. Line ends OK in f-strings for lexer.python.strings.over.newline=1.
-rw-r--r--lexers/LexPython.cxx54
1 files changed, 36 insertions, 18 deletions
diff --git a/lexers/LexPython.cxx b/lexers/LexPython.cxx
index b20d3ad25..6c11fb0c8 100644
--- a/lexers/LexPython.cxx
+++ b/lexers/LexPython.cxx
@@ -351,6 +351,9 @@ public:
static ILexer *LexerFactoryPython() {
return new LexerPython();
}
+
+private:
+ void ProcessLineEnd(StyleContext &sc, int *fstringStateStack, bool &inContinuedString) const;
};
Sci_Position SCI_METHOD LexerPython::PropertySet(const char *key, const char *val) {
@@ -382,10 +385,33 @@ Sci_Position SCI_METHOD LexerPython::WordListSet(int n, const char *wl) {
return firstModification;
}
+void LexerPython::ProcessLineEnd(StyleContext &sc, int *fstringStateStack, bool &inContinuedString) const {
+ // Restore to to outermost string state if in an f-string expression and
+ // let code below decide what to do
+ while (fstringStateStack[0] != 0) {
+ sc.SetState(PopFromStateStack(fstringStateStack, 4));
+ }
+
+ if ((sc.state == SCE_P_DEFAULT)
+ || IsPyTripleQuoteStringState(sc.state)) {
+ // Perform colourisation of white space and triple quoted strings at end of each line to allow
+ // tab marking to work inside white space and triple quoted strings
+ sc.SetState(sc.state);
+ }
+ if (IsPySingleQuoteStringState(sc.state)) {
+ if (inContinuedString || options.stringsOverNewline) {
+ inContinuedString = false;
+ } else {
+ sc.ChangeState(SCE_P_STRINGEOL);
+ sc.ForwardSetState(SCE_P_DEFAULT);
+ }
+ }
+}
+
void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, int initStyle, IDocument *pAccess) {
Accessor styler(pAccess, NULL);
- // Track whether in f-string exp; an array is used for a stack to
+ // Track whether in f-string expression; an array is used for a stack to
// handle nested f-strings such as f"""{f'''{f"{f'{1}'}"}'''}"""
int fstringStateStack[4] = { 0, };
const Sci_Position endPos = startPos + length;
@@ -453,21 +479,8 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
}
if (sc.atLineEnd) {
- if ((sc.state == SCE_P_DEFAULT)
- || IsPyTripleQuoteStringState(sc.state)) {
- // Perform colourisation of white space and triple quoted strings at end of each line to allow
- // tab marking to work inside white space and triple quoted strings
- sc.SetState(sc.state);
- }
+ ProcessLineEnd(sc, fstringStateStack, inContinuedString);
lineCurrent++;
- if (IsPySingleQuoteStringState(sc.state)) {
- if (inContinuedString || options.stringsOverNewline) {
- inContinuedString = false;
- } else {
- sc.ChangeState(SCE_P_STRINGEOL);
- sc.ForwardSetState(SCE_P_DEFAULT);
- }
- }
if (!sc.More())
break;
}
@@ -608,6 +621,7 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
PushStateToStack(sc.state, fstringStateStack, ELEMENTS(fstringStateStack));
sc.ForwardSetState(SCE_P_DEFAULT);
}
+ needEOLCheck = true;
}
// End of code to find the end of a state
@@ -624,17 +638,21 @@ void SCI_METHOD LexerPython::Lex(Sci_PositionU startPos, Sci_Position length, in
// State exit code may have moved on to end of line
if (needEOLCheck && sc.atLineEnd) {
+ ProcessLineEnd(sc, fstringStateStack, inContinuedString);
lineCurrent++;
styler.IndentAmount(lineCurrent, &spaceFlags, IsPyComment);
if (!sc.More())
break;
}
+ // If in f-string expression, check for } to resume f-string state
+ if (fstringStateStack[0] != 0 && sc.ch == '}') {
+ sc.SetState(PopFromStateStack(fstringStateStack, ELEMENTS(fstringStateStack)));
+ }
+
// Check for a new state starting character
if (sc.state == SCE_P_DEFAULT) {
- if (fstringStateStack[0] != 0 && sc.ch == '}') {
- sc.SetState(PopFromStateStack(fstringStateStack, ELEMENTS(fstringStateStack)));
- } else if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
+ if (IsADigit(sc.ch) || (sc.ch == '.' && IsADigit(sc.chNext))) {
if (sc.ch == '0' && (sc.chNext == 'x' || sc.chNext == 'X')) {
base_n_number = true;
sc.SetState(SCE_P_NUMBER);