aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Lakhtanov <ivan.lakhtanov@gmail.com>2016-08-20 02:25:30 (GMT)
committerIvan Lakhtanov <ivan.lakhtanov@gmail.com>2016-08-20 02:33:01 (GMT)
commit5eb7ca2a5a6339445d82e09d5494244535bcf504 (patch)
tree1fa9266ccf899269c15424821e254481519e9119
parent073b3eec9a4c54f444da05b5b395f6e79963d447 (diff)
Fixed python syntax highlight of strings and commentsvaness-python-highlight-fix
Now parsing text block by block to parse comments in strings and strings in comments right Differential Revision: https://phabricator.kde.org/D2016
-rw-r--r--src/backends/python/pythonhighlighter.cpp129
-rw-r--r--src/backends/python/pythonhighlighter.h1
2 files changed, 89 insertions, 41 deletions
diff --git a/src/backends/python/pythonhighlighter.cpp b/src/backends/python/pythonhighlighter.cpp
index 34d894b..4064524 100644
--- a/src/backends/python/pythonhighlighter.cpp
+++ b/src/backends/python/pythonhighlighter.cpp
@@ -27,63 +27,118 @@
PythonHighlighter::PythonHighlighter(QObject* parent) : Cantor::DefaultHighlighter(parent)
{
qDebug() << "PythonHighlighter construtor";
- addRule(QRegExp(QLatin1String("\\b[A-Za-z0-9_]+(?=\\()")), functionFormat());
+ addRule(QRegExp(QLatin1String("\\b\\w+(?=\\()")), functionFormat());
//Code highlighting the different keywords
addKeywords(PythonKeywords::instance()->keywords());
-
- addRule(QLatin1String("FIXME"), commentFormat());
- addRule(QLatin1String("TODO"), commentFormat());
-
addFunctions(PythonKeywords::instance()->functions());
addVariables(PythonKeywords::instance()->variables());
-
- addRule(QRegExp(QLatin1String("\".*\"")), stringFormat());
- addRule(QRegExp(QLatin1String("'.*'")), stringFormat());
- addRule(QRegExp(QLatin1String("#[^\n]*")), commentFormat());
-
- commentStartExpression = QRegExp(QLatin1String("'''[^\n]*"));
- commentEndExpression = QRegExp(QLatin1String("'''"));
}
PythonHighlighter::~PythonHighlighter()
{
}
-void PythonHighlighter::highlightBlock(const QString& text)
+void PythonHighlighter::highlightBlock(const QString &text)
{
- qDebug() << "PythonHighlighter::highlightBlock";
- qDebug() << "text: " << text;
-
- if (skipHighlighting(text)){
- qDebug() << "skipHighlighting(" << text << " ) " << "== true";
+ if (skipHighlighting(text)) {
return;
}
- //Do some backend independent highlighting (brackets etc.)
+ // Do some backend independent highlighting (brackets etc.)
DefaultHighlighter::highlightBlock(text);
- setCurrentBlockState(0);
+ const int IN_MULTILINE_COMMENT = 1;
+ const int IN_SMALL_QUOTE_STRING = 2;
+ const int IN_SINGLE_QUOTE_STRING = 4;
+ const int IN_TRIPLE_QUOTE_STRING = 8;
- int startIndex = 0;
- if (previousBlockState() != 1)
- startIndex = commentStartExpression.indexIn(text);
+ QRegExp multiLineCommentStartEnd(QLatin1String("'''"));
+ QRegExp smallQuoteStartEnd(QLatin1String("'"));
+ QRegExp singleQuoteStringStartEnd(QLatin1String("\""));
+ QRegExp tripleQuoteStringStartEnd(QLatin1String("\"\"\""));
+ QRegExp singleLineCommentStart(QLatin1String("#"));
- while (startIndex >= 0) {
+ int state = previousBlockState();
+ if (state == -1) {
+ state = 0;
+ }
- int endIndex = commentEndExpression.indexIn(text, startIndex);
- int commentLength;
- if (endIndex == -1) {
+ QList<int> flags = {
+ IN_TRIPLE_QUOTE_STRING,
+ IN_SINGLE_QUOTE_STRING,
+ IN_SMALL_QUOTE_STRING,
+ IN_MULTILINE_COMMENT
+ };
+ QList<QRegExp> regexps = {
+ tripleQuoteStringStartEnd,
+ singleQuoteStringStartEnd,
+ smallQuoteStartEnd,
+ multiLineCommentStartEnd
+ };
+ QList<QTextCharFormat> formats = {
+ stringFormat(),
+ stringFormat(),
+ stringFormat(),
+ commentFormat()
+ };
+
+ int pos = 0;
+ while (pos < text.length()) {
+ // Trying to close current environments
+ bool triggered = false;
+ for (int i = 0; i < flags.size() and not triggered; i++) {
+ int flag = flags[i];
+ QRegExp &regexp = regexps[i];
+ QTextCharFormat &format = formats[i];
+ if (state & flag) {
+ int new_pos = regexp.indexIn(text, pos);
+ int length;
+ if (new_pos == -1) {
+ length = text.length() - pos;
+ } else {
+ length = new_pos - pos + regexp.matchedLength();
+ state -= flag;
+ }
+ setFormat(pos, length, format);
+ pos = pos + length;
+ triggered = true;
+ }
+ }
+ if (triggered) {
+ continue;
+ }
- setCurrentBlockState(1);
- commentLength = text.length() - startIndex;
- } else {
- commentLength = endIndex - startIndex
- + commentEndExpression.matchedLength();
+ QRegExp *minRegexp = nullptr;
+ int minPos = INT_MAX;
+ int minIdx = -1;
+ for (int i = 0; i < regexps.size(); i++) {
+ QRegExp &regexp = regexps[i];
+ int newPos = regexp.indexIn(text, pos);
+ if (newPos != -1) {
+ minPos = qMin(minPos, newPos);
+ minRegexp = &regexp;
+ minIdx = i;
+ }
}
- setFormat(startIndex, commentLength, commentFormat());
- startIndex = commentStartExpression.indexIn(text, startIndex + commentLength);
+
+ int singleLineCommentStartPos =
+ singleLineCommentStart.indexIn(text, pos);
+
+ if (singleLineCommentStartPos != -1
+ and singleLineCommentStartPos < minPos) {
+ setFormat(pos, text.length() - pos, commentFormat());
+ break;
+ } else if (minRegexp) {
+ state += flags[minIdx];
+ pos = minPos + minRegexp->matchedLength();
+ setFormat(minPos, minRegexp->matchedLength(), formats[minIdx]);
+ } else {
+ break;
+ }
}
+
+ setCurrentBlockState(state);
}
void PythonHighlighter::updateHighlight()
@@ -93,9 +148,3 @@ void PythonHighlighter::updateHighlight()
addVariables(PythonKeywords::instance()->variables());
rehighlight();
}
-
-QString PythonHighlighter::nonSeparatingCharacters() const
-{
- qDebug() << "PythonHighlighter::nonSeparatingCharacters() function";
- return QLatin1String("[%]");
-}
diff --git a/src/backends/python/pythonhighlighter.h b/src/backends/python/pythonhighlighter.h
index 3ef2dba..fa84a12 100644
--- a/src/backends/python/pythonhighlighter.h
+++ b/src/backends/python/pythonhighlighter.h
@@ -36,7 +36,6 @@ class PythonHighlighter : public Cantor::DefaultHighlighter
protected:
void highlightBlock(const QString& text);
- QString nonSeparatingCharacters() const;
private:
QRegExp commentStartExpression;