summaryrefslogtreecommitdiff
path: root/modules/gdscript/editor/gdscript_highlighter.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/gdscript/editor/gdscript_highlighter.cpp')
-rw-r--r--modules/gdscript/editor/gdscript_highlighter.cpp129
1 files changed, 84 insertions, 45 deletions
diff --git a/modules/gdscript/editor/gdscript_highlighter.cpp b/modules/gdscript/editor/gdscript_highlighter.cpp
index 6529154e5c..e3f0ddfc35 100644
--- a/modules/gdscript/editor/gdscript_highlighter.cpp
+++ b/modules/gdscript/editor/gdscript_highlighter.cpp
@@ -5,8 +5,8 @@
/* GODOT ENGINE */
/* https://godotengine.org */
/*************************************************************************/
-/* Copyright (c) 2007-2021 Juan Linietsky, Ariel Manzur. */
-/* Copyright (c) 2014-2021 Godot Engine contributors (cf. AUTHORS.md). */
+/* Copyright (c) 2007-2022 Juan Linietsky, Ariel Manzur. */
+/* Copyright (c) 2014-2022 Godot Engine contributors (cf. AUTHORS.md). */
/* */
/* Permission is hereby granted, free of charge, to any person obtaining */
/* a copy of this software and associated documentation files (the */
@@ -31,20 +31,9 @@
#include "gdscript_highlighter.h"
#include "../gdscript.h"
#include "../gdscript_tokenizer.h"
+#include "core/config/project_settings.h"
#include "editor/editor_settings.h"
-static bool _is_char(char32_t c) {
- return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_';
-}
-
-static bool _is_hex_symbol(char32_t c) {
- return ((c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F'));
-}
-
-static bool _is_bin_symbol(char32_t c) {
- return (c == '0' || c == '1');
-}
-
Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_line) {
Dictionary color_map;
@@ -60,7 +49,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
bool in_keyword = false;
bool in_word = false;
bool in_function_name = false;
+ bool in_lambda = false;
bool in_variable_declaration = false;
+ bool in_signal_declaration = false;
bool in_function_args = false;
bool in_member_variable = false;
bool in_node_path = false;
@@ -100,17 +91,20 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
color = font_color;
bool is_char = !is_symbol(str[j]);
bool is_a_symbol = is_symbol(str[j]);
- bool is_number = (str[j] >= '0' && str[j] <= '9');
+ bool is_number = is_digit(str[j]);
/* color regions */
if (is_a_symbol || in_region != -1) {
int from = j;
- for (; from < line_length; from++) {
- if (str[from] == '\\') {
- from++;
- continue;
+
+ if (in_region == -1) {
+ for (; from < line_length; from++) {
+ if (str[from] == '\\') {
+ from++;
+ continue;
+ }
+ break;
}
- break;
}
if (from != line_length) {
@@ -142,6 +136,12 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
/* check if it's the whole line */
if (end_key_length == 0 || color_regions[c].line_only || from + end_key_length > line_length) {
+ if (from + end_key_length > line_length) {
+ // If it's key length and there is a '\', dont skip to highlight esc chars.
+ if (str.find("\\", from) >= 0) {
+ break;
+ }
+ }
prev_color = color_regions[in_region].color;
highlighter_info["color"] = color_regions[c].color;
color_map[j] = highlighter_info;
@@ -161,13 +161,25 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
/* if we are in one find the end key */
if (in_region != -1) {
+ Color region_color = color_regions[in_region].color;
+ if (in_node_path && (color_regions[in_region].start_key == "\"" || color_regions[in_region].start_key == "\'")) {
+ region_color = node_path_color;
+ }
+
+ prev_color = region_color;
+ highlighter_info["color"] = region_color;
+ color_map[j] = highlighter_info;
+
/* search the line */
int region_end_index = -1;
int end_key_length = color_regions[in_region].end_key.length();
const char32_t *end_key = color_regions[in_region].end_key.get_data();
for (; from < line_length; from++) {
if (line_length - from < end_key_length) {
- break;
+ // Don't break if '\' to highlight esc chars.
+ if (str.find("\\", from) < 0) {
+ break;
+ }
}
if (!is_symbol(str[from])) {
@@ -175,7 +187,16 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
if (str[from] == '\\') {
+ Dictionary escape_char_highlighter_info;
+ escape_char_highlighter_info["color"] = symbol_color;
+ color_map[from] = escape_char_highlighter_info;
+
from++;
+
+ Dictionary region_continue_highlighter_info;
+ prev_color = region_color;
+ region_continue_highlighter_info["color"] = region_color;
+ color_map[from + 1] = region_continue_highlighter_info;
continue;
}
@@ -192,10 +213,6 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
}
- prev_color = color_regions[in_region].color;
- highlighter_info["color"] = color_regions[in_region].color;
- color_map[j] = highlighter_info;
-
previous_type = REGION;
previous_text = "";
previous_column = j;
@@ -213,14 +230,14 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
// allow ABCDEF in hex notation
- if (is_hex_notation && (_is_hex_symbol(str[j]) || is_number)) {
+ if (is_hex_notation && (is_hex_digit(str[j]) || is_number)) {
is_number = true;
} else {
is_hex_notation = false;
}
// disallow anything not a 0 or 1
- if (is_bin_notation && (_is_bin_symbol(str[j]))) {
+ if (is_bin_notation && (is_binary_digit(str[j]))) {
is_number = true;
} else if (is_bin_notation) {
is_bin_notation = false;
@@ -242,7 +259,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
}
- if (!in_word && _is_char(str[j]) && !is_number) {
+ if (!in_word && (is_ascii_char(str[j]) || is_underscore(str[j])) && !is_number) {
in_word = true;
}
@@ -289,20 +306,36 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
if (!in_function_name && in_word && !in_keyword) {
- int k = j;
- while (k < str.length() && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
- k++;
- }
+ if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::SIGNAL)) {
+ in_signal_declaration = true;
+ } else {
+ int k = j;
+ while (k < str.length() && !is_symbol(str[k]) && str[k] != '\t' && str[k] != ' ') {
+ k++;
+ }
- // check for space between name and bracket
- while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) {
- k++;
- }
+ // check for space between name and bracket
+ while (k < str.length() && (str[k] == '\t' || str[k] == ' ')) {
+ k++;
+ }
+
+ if (str[k] == '(') {
+ in_function_name = true;
+ } else if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) {
+ in_variable_declaration = true;
+ }
+
+ // Check for lambda.
+ if (in_function_name && previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
+ k = j - 1;
+ while (k > 0 && (str[k] == '\t' || str[k] == ' ')) {
+ k--;
+ }
- if (str[k] == '(') {
- in_function_name = true;
- } else if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::VAR)) {
- in_variable_declaration = true;
+ if (str[k] == ':') {
+ in_lambda = true;
+ }
+ }
}
}
@@ -348,7 +381,9 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
}
in_variable_declaration = false;
+ in_signal_declaration = false;
in_function_name = false;
+ in_lambda = false;
in_member_variable = false;
}
@@ -376,10 +411,14 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
} else if (in_member_variable) {
next_type = MEMBER;
color = member_color;
+ } else if (in_signal_declaration) {
+ next_type = SIGNAL;
+
+ color = member_color;
} else if (in_function_name) {
next_type = FUNCTION;
- if (previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
+ if (!in_lambda && previous_text == GDScriptTokenizer::get_token_name(GDScriptTokenizer::Token::FUNC)) {
color = function_definition_color;
} else {
color = function_color;
@@ -413,7 +452,7 @@ Dictionary GDScriptSyntaxHighlighter::_get_line_syntax_highlighting_impl(int p_l
previous_column = j;
// ignore if just whitespace
- if (text != "") {
+ if (!text.is_empty()) {
previous_text = text;
}
}
@@ -509,7 +548,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
for (const String &comment : comments) {
String beg = comment.get_slice(" ", 0);
String end = comment.get_slice_count(" ") > 1 ? comment.get_slice(" ", 1) : String();
- add_color_region(beg, end, comment_color, end == "");
+ add_color_region(beg, end, comment_color, end.is_empty());
}
/* Strings */
@@ -519,7 +558,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
for (const String &string : strings) {
String beg = string.get_slice(" ", 0);
String end = string.get_slice_count(" ") > 1 ? string.get_slice(" ", 1) : String();
- add_color_region(beg, end, string_color, end == "");
+ add_color_region(beg, end, string_color, end.is_empty());
}
const Ref<Script> script = _get_edited_resource();
@@ -535,7 +574,7 @@ void GDScriptSyntaxHighlighter::_update_cache() {
if (E.usage & PROPERTY_USAGE_CATEGORY || E.usage & PROPERTY_USAGE_GROUP || E.usage & PROPERTY_USAGE_SUBGROUP) {
continue;
}
- if (name.find("/") != -1) {
+ if (name.contains("/")) {
continue;
}
member_keywords[name] = member_variable_color;