summaryrefslogtreecommitdiff
path: root/scene/gui/code_edit.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'scene/gui/code_edit.cpp')
-rw-r--r--scene/gui/code_edit.cpp158
1 files changed, 109 insertions, 49 deletions
diff --git a/scene/gui/code_edit.cpp b/scene/gui/code_edit.cpp
index 7fba94da4c..398b909195 100644
--- a/scene/gui/code_edit.cpp
+++ b/scene/gui/code_edit.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 */
@@ -143,7 +143,6 @@ void CodeEdit::_notification(int p_what) {
code_completion_line_ofs = CLAMP(code_completion_current_selected - lines / 2, 0, code_completion_options_count - lines);
RenderingServer::get_singleton()->canvas_item_add_rect(ci, Rect2(Point2(code_completion_rect.position.x, code_completion_rect.position.y + (code_completion_current_selected - code_completion_line_ofs) * row_height), Size2(code_completion_rect.size.width, row_height)), code_completion_selected_color);
- draw_rect(Rect2(code_completion_rect.position + Vector2(icon_area_size.x + icon_hsep, 0), Size2(MIN(code_completion_base_width, code_completion_rect.size.width - (icon_area_size.x + icon_hsep)), code_completion_rect.size.height)), code_completion_existing_color);
for (int i = 0; i < lines; i++) {
int l = code_completion_line_ofs + i;
@@ -170,13 +169,24 @@ void CodeEdit::_notification(int p_what) {
if (code_completion_options[l].default_value.get_type() == Variant::COLOR) {
draw_rect(Rect2(Point2(code_completion_rect.position.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value);
}
- tl->set_align(HALIGN_RIGHT);
+ tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_RIGHT);
} else {
if (code_completion_options[l].default_value.get_type() == Variant::COLOR) {
draw_rect(Rect2(Point2(code_completion_rect.position.x + code_completion_rect.size.width - icon_area_size.x, icon_area.position.y), icon_area_size), (Color)code_completion_options[l].default_value);
}
- tl->set_align(HALIGN_LEFT);
+ tl->set_horizontal_alignment(HORIZONTAL_ALIGNMENT_LEFT);
}
+
+ Point2 match_pos = Point2(code_completion_rect.position.x + icon_area_size.x + icon_hsep, code_completion_rect.position.y + i * row_height);
+
+ for (int j = 0; j < code_completion_options[l].matches.size(); j++) {
+ Pair<int, int> match = code_completion_options[l].matches[j];
+ int match_offset = font->get_string_size(code_completion_options[l].display.substr(0, match.first), font_size).width;
+ int match_len = font->get_string_size(code_completion_options[l].display.substr(match.first, match.second), font_size).width;
+
+ draw_rect(Rect2(match_pos + Point2(match_offset, 0), Size2(match_len, row_height)), code_completion_existing_color);
+ }
+
tl->draw(ci, title_pos, code_completion_options[l].font_color);
}
@@ -189,7 +199,7 @@ void CodeEdit::_notification(int p_what) {
}
/* Code hint */
- if (caret_visible && code_hint != "" && (!code_completion_active || (code_completion_below != code_hint_draw_below))) {
+ if (caret_visible && !code_hint.is_empty() && (!code_completion_active || (code_completion_below != code_hint_draw_below))) {
const int font_height = font->get_height(font_size);
Ref<StyleBox> sb = get_theme_stylebox(SNAME("panel"), SNAME("TooltipPanel"));
Color font_color = get_theme_color(SNAME("font_color"), SNAME("TooltipLabel"));
@@ -229,7 +239,7 @@ void CodeEdit::_notification(int p_what) {
Point2 round_ofs = hint_ofs + sb->get_offset() + Vector2(0, font->get_ascent(font_size) + font_height * i + yofs);
round_ofs = round_ofs.round();
- draw_string(font, round_ofs, line.replace(String::chr(0xFFFF), ""), HALIGN_LEFT, -1, font_size, font_color);
+ draw_string(font, round_ofs, line.replace(String::chr(0xFFFF), ""), HORIZONTAL_ALIGNMENT_LEFT, -1, font_size, font_color);
if (end > 0) {
// Draw an underline for the currently edited function parameter.
const Vector2 b = hint_ofs + sb->get_offset() + Vector2(begin, font_height + font_height * i + yofs);
@@ -315,7 +325,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
}
} else {
if (mb->get_button_index() == MouseButton::LEFT) {
- if (mb->is_command_pressed() && symbol_lookup_word != String()) {
+ if (mb->is_command_pressed() && !symbol_lookup_word.is_empty()) {
Vector2i mpos = mb->get_position();
if (is_layout_rtl()) {
mpos.x = get_size().x - mpos.x;
@@ -530,7 +540,7 @@ void CodeEdit::gui_input(const Ref<InputEvent> &p_gui_input) {
/* General overrides */
Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const {
- if (symbol_lookup_word != String()) {
+ if (!symbol_lookup_word.is_empty()) {
return CURSOR_POINTING_HAND;
}
@@ -1419,40 +1429,23 @@ void CodeEdit::fold_line(int p_line) {
/* End line is the same therefore we have a block of single line delimiters. */
if (end_line == p_line) {
for (int i = p_line + 1; i <= line_count; i++) {
- if (i == line_count) {
- end_line = line_count;
- break;
- }
-
if ((in_string != -1 && is_in_string(i) == -1) || (in_comment != -1 && is_in_comment(i) == -1)) {
- end_line = i - 1;
break;
}
+ end_line = i;
}
}
} else {
int start_indent = get_indent_level(p_line);
for (int i = p_line + 1; i <= line_count; i++) {
- if (get_line(p_line).strip_edges().size() == 0 || is_in_string(i) != -1 || is_in_comment(i) != -1) {
- end_line = i;
+ if (get_line(i).strip_edges().size() == 0) {
continue;
}
-
- if (i == line_count) {
- /* Do not fold empty last line of script if any */
+ if (get_indent_level(i) > start_indent) {
end_line = i;
- if (get_line(i).strip_edges().size() == 0) {
- end_line--;
- }
- break;
+ continue;
}
-
- if ((get_indent_level(i) <= start_indent && get_line(i).strip_edges().size() != 0)) {
- /* Keep an empty line unfolded if any */
- end_line = i - 1;
- if (get_line(i - 1).strip_edges().size() == 0 && i - 2 > p_line) {
- end_line = i - 2;
- }
+ if (is_in_string(i) == -1 && is_in_comment(i) == -1) {
break;
}
}
@@ -2395,7 +2388,7 @@ void CodeEdit::_update_delimiter_cache(int p_from_line, int p_to_line) {
if (start_line != end_line) {
if (p_to_line < p_from_line) {
for (int i = end_line; i > start_line; i--) {
- delimiter_cache.remove(i);
+ delimiter_cache.remove_at(i);
}
} else {
for (int i = start_line; i < end_line; i++) {
@@ -2614,7 +2607,7 @@ void CodeEdit::_add_delimiter(const String &p_start_key, const String &p_end_key
delimiter.type = p_type;
delimiter.start_key = p_start_key;
delimiter.end_key = p_end_key;
- delimiter.line_only = p_line_only || p_end_key == "";
+ delimiter.line_only = p_line_only || p_end_key.is_empty();
delimiters.insert(at, delimiter);
if (!setting_delimiters) {
delimiter_cache.clear();
@@ -2632,7 +2625,7 @@ void CodeEdit::_remove_delimiter(const String &p_start_key, DelimiterType p_type
break;
}
- delimiters.remove(i);
+ delimiters.remove_at(i);
if (!setting_delimiters) {
delimiter_cache.clear();
_update_delimiter_cache();
@@ -2664,7 +2657,7 @@ void CodeEdit::_set_delimiters(const TypedArray<String> &p_delimiters, Delimiter
const String start_key = key.get_slice(" ", 0);
const String end_key = key.get_slice_count(" ") > 1 ? key.get_slice(" ", 1) : String();
- _add_delimiter(start_key, end_key, end_key == "", p_type);
+ _add_delimiter(start_key, end_key, end_key.is_empty(), p_type);
}
setting_delimiters = false;
_update_delimiter_cache();
@@ -2673,7 +2666,7 @@ void CodeEdit::_set_delimiters(const TypedArray<String> &p_delimiters, Delimiter
void CodeEdit::_clear_delimiters(DelimiterType p_type) {
for (int i = delimiters.size() - 1; i >= 0; i--) {
if (delimiters[i].type == p_type) {
- delimiters.remove(i);
+ delimiters.remove_at(i);
}
}
delimiter_cache.clear();
@@ -2825,6 +2818,8 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
code_completion_base = string_to_complete;
Vector<ScriptCodeCompletionOption> completion_options_casei;
+ Vector<ScriptCodeCompletionOption> completion_options_substr;
+ Vector<ScriptCodeCompletionOption> completion_options_substr_casei;
Vector<ScriptCodeCompletionOption> completion_options_subseq;
Vector<ScriptCodeCompletionOption> completion_options_subseq_casei;
@@ -2879,35 +2874,100 @@ void CodeEdit::_filter_code_completion_candidates_impl() {
const char32_t *tgt = &option.display[0];
const char32_t *tgt_lower = &display_lower[0];
- const char32_t *ssq_last_tgt = nullptr;
- const char32_t *ssq_lower_last_tgt = nullptr;
+ const char32_t *sst = &string_to_complete[0];
+ const char32_t *sst_lower = &display_lower[0];
- for (; *tgt; tgt++, tgt_lower++) {
+ Vector<Pair<int, int>> ssq_matches;
+ int ssq_match_start = 0;
+ int ssq_match_len = 0;
+
+ Vector<Pair<int, int>> ssq_lower_matches;
+ int ssq_lower_match_start = 0;
+ int ssq_lower_match_len = 0;
+
+ int sst_start = -1;
+ int sst_lower_start = -1;
+
+ for (int i = 0; *tgt; tgt++, tgt_lower++, i++) {
+ // Check substring.
+ if (*sst == *tgt) {
+ sst++;
+ if (sst_start == -1) {
+ sst_start = i;
+ }
+ } else if (sst_start != -1 && *sst) {
+ sst = &string_to_complete[0];
+ sst_start = -1;
+ }
+
+ // Check subsequence.
if (*ssq == *tgt) {
ssq++;
- ssq_last_tgt = tgt;
+ if (ssq_match_len == 0) {
+ ssq_match_start = i;
+ }
+ ssq_match_len++;
+ } else if (ssq_match_len > 0) {
+ ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len));
+ ssq_match_len = 0;
+ }
+
+ // Check lower substring.
+ if (*sst_lower == *tgt) {
+ sst_lower++;
+ if (sst_lower_start == -1) {
+ sst_lower_start = i;
+ }
+ } else if (sst_lower_start != -1 && *sst_lower) {
+ sst_lower = &string_to_complete[0];
+ sst_lower_start = -1;
}
+
+ // Check lower subsequence.
if (*ssq_lower == *tgt_lower) {
ssq_lower++;
- ssq_lower_last_tgt = tgt;
+ if (ssq_lower_match_len == 0) {
+ ssq_lower_match_start = i;
+ }
+ ssq_lower_match_len++;
+ } else if (ssq_lower_match_len > 0) {
+ ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len));
+ ssq_lower_match_len = 0;
}
}
/* Matched the whole subsequence in s. */
- if (!*ssq) {
- /* Finished matching in the first s.length() characters. */
- if (ssq_last_tgt == &option.display[string_to_complete.length() - 1]) {
+ if (!*ssq) { // Matched the whole subsequence in s.
+ option.matches.clear();
+
+ if (sst_start == 0) { // Matched substring in beginning of s.
+ option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length()));
code_completion_options.push_back(option);
+ } else if (sst_start > 0) { // Matched substring in s.
+ option.matches.push_back(Pair<int, int>(sst_start, string_to_complete.length()));
+ completion_options_substr.push_back(option);
} else {
+ if (ssq_match_len > 0) {
+ ssq_matches.push_back(Pair<int, int>(ssq_match_start, ssq_match_len));
+ }
+ option.matches.append_array(ssq_matches);
completion_options_subseq.push_back(option);
}
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
- /* Matched the whole subsequence in s_lower. */
- } else if (!*ssq_lower) {
- /* Finished matching in the first s.length() characters. */
- if (ssq_lower_last_tgt == &option.display[string_to_complete.length() - 1]) {
+ } else if (!*ssq_lower) { // Matched the whole subsequence in s_lower.
+ option.matches.clear();
+
+ if (sst_lower_start == 0) { // Matched substring in beginning of s_lower.
+ option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length()));
completion_options_casei.push_back(option);
+ } else if (sst_lower_start > 0) { // Matched substring in s_lower.
+ option.matches.push_back(Pair<int, int>(sst_lower_start, string_to_complete.length()));
+ completion_options_substr_casei.push_back(option);
} else {
+ if (ssq_lower_match_len > 0) {
+ ssq_lower_matches.push_back(Pair<int, int>(ssq_lower_match_start, ssq_lower_match_len));
+ }
+ option.matches.append_array(ssq_lower_matches);
completion_options_subseq_casei.push_back(option);
}
max_width = MAX(max_width, font->get_string_size(option.display, font_size).width + offset);
@@ -3007,7 +3067,7 @@ CodeEdit::CodeEdit() {
add_auto_brace_completion_pair("\"", "\"");
add_auto_brace_completion_pair("\'", "\'");
- /* Delimiter traking */
+ /* Delimiter tracking */
add_string_delimiter("\"", "\"", false);
add_string_delimiter("\'", "\'", false);