Changeset View
Changeset View
Standalone View
Standalone View
src/backends/julia/juliahighlighter.cpp
Context not available. | |||||
41 | // Do some backend independent highlighting (brackets etc.) | 41 | // Do some backend independent highlighting (brackets etc.) | ||
---|---|---|---|---|---|
42 | DefaultHighlighter::highlightBlock(text); | 42 | DefaultHighlighter::highlightBlock(text); | ||
43 | 43 | | |||
44 | // Now we are about to make corrent strings and comments highlighting | ||||
45 | // | ||||
46 | // Main idea: as soon as string starts comment or anything else cant start | ||||
47 | // until current string ends. The same with comment, except '#' comment | ||||
48 | // that ends by newline | ||||
49 | // | ||||
50 | // To pass information to next block, we are using next states | ||||
44 | const int IN_MULTILINE_COMMENT = 1; | 51 | const int IN_MULTILINE_COMMENT = 1; | ||
45 | const int IN_CHARACTER = 2; | 52 | const int IN_CHARACTER = 2; | ||
46 | const int IN_SINGLE_QUOTE_STRING = 4; | 53 | const int IN_SINGLE_QUOTE_STRING = 4; | ||
47 | const int IN_TRIPLE_QUOTE_STRING = 8; | 54 | const int IN_TRIPLE_QUOTE_STRING = 8; | ||
48 | 55 | | |||
56 | // Markers of scopes start, ends | ||||
49 | QRegExp multiLineCommentStart(QLatin1String("#=")); | 57 | QRegExp multiLineCommentStart(QLatin1String("#=")); | ||
50 | QRegExp multiLineCommentEnd(QLatin1String("=#")); | 58 | QRegExp multiLineCommentEnd(QLatin1String("=#")); | ||
51 | QRegExp characterStartEnd(QLatin1String("'")); | 59 | QRegExp characterStartEnd(QLatin1String("'")); | ||
Context not available. | |||||
53 | QRegExp tripleQuoteStringStartEnd(QLatin1String("\"\"\"")); | 61 | QRegExp tripleQuoteStringStartEnd(QLatin1String("\"\"\"")); | ||
54 | QRegExp singleLineCommentStart(QLatin1String("#(?!=)")); | 62 | QRegExp singleLineCommentStart(QLatin1String("#(?!=)")); | ||
55 | 63 | | |||
64 | // Get current state | ||||
56 | int state = previousBlockState(); | 65 | int state = previousBlockState(); | ||
57 | if (state == -1) { | 66 | if (state == -1) { | ||
58 | state = 0; | 67 | state = 0; | ||
59 | } | 68 | } | ||
60 | 69 | | |||
70 | // This 4 arrays establish matching between state, start marker, end marker | ||||
71 | // and format to apply | ||||
61 | QList<int> flags = { | 72 | QList<int> flags = { | ||
62 | IN_TRIPLE_QUOTE_STRING, | 73 | IN_TRIPLE_QUOTE_STRING, | ||
63 | IN_SINGLE_QUOTE_STRING, | 74 | IN_SINGLE_QUOTE_STRING, | ||
Context not available. | |||||
83 | commentFormat() | 94 | commentFormat() | ||
84 | }; | 95 | }; | ||
85 | 96 | | |||
86 | int pos = 0; | 97 | int pos = 0; // current position in block | ||
87 | while (pos < text.length()) { | 98 | while (pos < text.length()) { | ||
88 | // Trying to close current environments | 99 | // Trying to close current environments | ||
89 | bool triggered = false; | 100 | bool triggered = false; | ||
Context not available. | |||||
91 | int flag = flags[i]; | 102 | int flag = flags[i]; | ||
92 | QRegExp ®exp = regexps_ends[i]; | 103 | QRegExp ®exp = regexps_ends[i]; | ||
93 | QTextCharFormat &format = formats[i]; | 104 | QTextCharFormat &format = formats[i]; | ||
94 | if (state & flag) { | 105 | if (state & flag) { // Found current state | ||
106 | // find where end marker is | ||||
95 | int new_pos = regexp.indexIn(text, pos); | 107 | int new_pos = regexp.indexIn(text, pos); | ||
96 | int length; | 108 | int length; | ||
97 | if (new_pos == -1) { | 109 | if (new_pos == -1) { | ||
110 | // not in this block, highlight till the end | ||||
98 | length = text.length() - pos; | 111 | length = text.length() - pos; | ||
99 | } else { | 112 | } else { | ||
113 | // highlight untill the marker and modify state | ||||
100 | length = new_pos - pos + regexp.matchedLength(); | 114 | length = new_pos - pos + regexp.matchedLength(); | ||
101 | state -= flag; | 115 | state -= flag; | ||
102 | } | 116 | } | ||
117 | // Apply format to the found area | ||||
103 | setFormat(pos, length, format); | 118 | setFormat(pos, length, format); | ||
104 | pos = pos + length; | 119 | pos = pos + length; | ||
105 | triggered = true; | 120 | triggered = true; | ||
106 | } | 121 | } | ||
107 | } | 122 | } | ||
108 | if (triggered) { | 123 | if (triggered) { // We have done something move to next iteration | ||
109 | continue; | 124 | continue; | ||
110 | } | 125 | } | ||
111 | 126 | | |||
112 | QRegExp *minRegexp = nullptr; | 127 | // Now we should found the scope that start the closest to current | ||
113 | int minPos = INT_MAX; | 128 | // position | ||
114 | int minIdx = -1; | 129 | QRegExp *minRegexp = nullptr; // closest marker | ||
130 | int minPos = INT_MAX; // closest pos | ||||
131 | int minIdx = -1; // closest scope index | ||||
115 | for (int i = 0; i < regexps_starts.size(); i++) { | 132 | for (int i = 0; i < regexps_starts.size(); i++) { | ||
116 | QRegExp ®exp = regexps_starts[i]; | 133 | QRegExp ®exp = regexps_starts[i]; | ||
117 | int newPos = regexp.indexIn(text, pos); | 134 | int newPos = regexp.indexIn(text, pos); | ||
Context not available. | |||||
122 | } | 139 | } | ||
123 | } | 140 | } | ||
124 | 141 | | |||
142 | // Check where single line comment starts | ||||
125 | int singleLineCommentStartPos = | 143 | int singleLineCommentStartPos = | ||
126 | singleLineCommentStart.indexIn(text, pos); | 144 | singleLineCommentStart.indexIn(text, pos); | ||
127 | 145 | | |||
128 | if (singleLineCommentStartPos != -1 | 146 | if (singleLineCommentStartPos != -1 | ||
129 | and singleLineCommentStartPos < minPos) { | 147 | and singleLineCommentStartPos < minPos) { | ||
148 | // single line comment starts earlier | ||||
130 | setFormat(pos, text.length() - pos, commentFormat()); | 149 | setFormat(pos, text.length() - pos, commentFormat()); | ||
131 | break; | 150 | break; | ||
132 | } else if (minRegexp) { | 151 | } else if (minRegexp) { | ||
152 | // We are going to another scope | ||||
133 | state += flags[minIdx]; | 153 | state += flags[minIdx]; | ||
134 | pos = minPos + minRegexp->matchedLength(); | 154 | pos = minPos + minRegexp->matchedLength(); | ||
135 | setFormat(minPos, minRegexp->matchedLength(), formats[minIdx]); | 155 | setFormat(minPos, minRegexp->matchedLength(), formats[minIdx]); | ||
136 | } else { | 156 | } else { // There is nothing to highlight | ||
137 | break; | 157 | break; | ||
138 | } | 158 | } | ||
139 | } | 159 | } | ||
Context not available. | |||||
143 | 163 | | |||
144 | void JuliaHighlighter::updateHighlight() | 164 | void JuliaHighlighter::updateHighlight() | ||
145 | { | 165 | { | ||
166 | // Remove rules for outdated variables and functions | ||||
146 | for (const auto &var : JuliaKeywords::instance()->removedVariables()) { | 167 | for (const auto &var : JuliaKeywords::instance()->removedVariables()) { | ||
147 | removeRule(var); | 168 | removeRule(var); | ||
148 | } | 169 | } | ||
149 | | ||||
150 | for (const auto &func : JuliaKeywords::instance()->removedFunctions()) { | 170 | for (const auto &func : JuliaKeywords::instance()->removedFunctions()) { | ||
151 | removeRule(func); | 171 | removeRule(func); | ||
152 | } | 172 | } | ||
153 | 173 | | |||
174 | // Add actual variables and function | ||||
154 | addVariables(JuliaKeywords::instance()->variables()); | 175 | addVariables(JuliaKeywords::instance()->variables()); | ||
155 | addFunctions(JuliaKeywords::instance()->functions()); | 176 | addFunctions(JuliaKeywords::instance()->functions()); | ||
156 | rehighlight(); | 177 | rehighlight(); | ||
Context not available. |