Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds occurrence auto completion #21742

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions core/ustring.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2265,6 +2265,78 @@ String String::substr(int p_from, int p_chars) const {
return s;
}

Array String::find_occurrences(const String &p_str, bool p_case_sensitive, int p_min_amount) const {

if (p_str.length() <= 0 || length() <= 0) {
return Array();
}

Array rs;
Array range = Array();
range.push_back(-1);
range.push_back(-1);
int s = 0;
String curr_str;
String curr_char2_ori;
String search_char_case = p_str.substr(s, 1);
String curr_char2;

for (int i = 0; i < length(); i++) {
curr_char2_ori = substr(i, 1);
if (!p_case_sensitive) {
search_char_case = search_char_case.to_lower();
curr_char2 = curr_char2_ori.to_lower();
} else {
curr_char2 = curr_char2_ori;
}

if (search_char_case == curr_char2) {
curr_str += curr_char2_ori;
if ((int)range[0] == -1) {
range[0] = i;
}
range[1] = i;
s++;
if (s < p_str.length()) {
search_char_case = p_str.substr(s, 1);
}

} else {
if (s < p_str.length()) {
if ((int)range[1] > -1) {
Array a = Array();
a.push_back(curr_str);
a.push_back(range);
rs.push_back(a);
range = Array();
range.push_back(-1);
range.push_back(-1);
curr_str = String();
}
} else {
break;
}
}
}

if (curr_str != String()) {
Array a = Array();
a.push_back(curr_str);
a.push_back(range);
rs.push_back(a);
}

if (p_min_amount == -1) {
if (s < p_str.length()) {
rs = Array();
}
} else if (s < p_min_amount) {
rs = Array();
}

return rs;
}

int String::find_last(const String &p_str) const {

int pos = -1;
Expand Down
1 change: 1 addition & 0 deletions core/ustring.h
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class String {

/* complex helpers */
String substr(int p_from, int p_chars) const;
Array find_occurrences(const String &p_str, bool p_case_sensitive = true, int p_min_amount = -1) const;
int find(const String &p_str, int p_from = 0) const; ///< return <0 if failed
int find(const char *p_str, int p_from) const; ///< return <0 if failed
int find_last(const String &p_str) const; ///< return <0 if failed
Expand Down
2 changes: 2 additions & 0 deletions core/variant_call.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ struct _VariantCall {
VCALL_LOCALMEM1R(String, nocasecmp_to);
VCALL_LOCALMEM0R(String, length);
VCALL_LOCALMEM2R(String, substr);
VCALL_LOCALMEM3R(String, find_occurrences);
VCALL_LOCALMEM2R(String, find);
VCALL_LOCALMEM1R(String, find_last);
VCALL_LOCALMEM2R(String, findn);
Expand Down Expand Up @@ -1477,6 +1478,7 @@ void register_variant_methods() {
ADDFUNC0R(STRING, INT, String, length, varray());
ADDFUNC2R(STRING, STRING, String, substr, INT, "from", INT, "len", varray());

ADDFUNC3R(STRING, ARRAY, String, find_occurrences, STRING, "search", BOOL, "case_sensitive", INT, "min_amount", varray(true, -1));
ADDFUNC2R(STRING, INT, String, find, STRING, "what", INT, "from", varray(0));

ADDFUNC1R(STRING, INT, String, find_last, STRING, "what", varray());
Expand Down
23 changes: 14 additions & 9 deletions scene/gui/text_edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5761,18 +5761,23 @@ void TextEdit::_update_completion_candidates() {
}

if (completion_options.size() == 0) {
List<Entry> entries;
//Collect
for (int i = 0; i < completion_strings.size(); i++) {
if (s.is_subsequence_of(completion_strings[i])) {
completion_options.push_back(completion_strings[i]);
String curr = completion_strings[i];
Entry entry;
entry.occurrences = curr.find_occurrences(s, false);
entry.word = curr;
entry.input = s;
if (entry.occurrences.size() > 0) {
entries.push_back(entry);
}
}
}

if (completion_options.size() == 0) {
for (int i = 0; i < completion_strings.size(); i++) {
if (s.is_subsequence_ofi(completion_strings[i])) {
completion_options.push_back(completion_strings[i]);
}
//Sort
entries.sort_custom<TextEdit::SortEntry>();
//apply
for (int i = 0; i < entries.size(); i++) {
completion_options.push_back(entries[i].word);
}
}

Expand Down
38 changes: 38 additions & 0 deletions scene/gui/text_edit.h
Original file line number Diff line number Diff line change
Expand Up @@ -439,6 +439,44 @@ class TextEdit : public Control {
ColorRegion _get_color_region(int p_region) const;
Map<int, Text::ColorRegionInfo> _get_line_color_region_info(int p_line) const;

struct Entry {
Array occurrences;
String word;
String input;
};

struct SortEntry {

bool operator()(Entry p_a, Entry p_b) const {

//Hack check case for first character
String input = p_a.input.substr(0, 1);
if (input != p_a.input.substr(0, 1).to_lower()) { //input is upper -> prefere upper results
if ((int)((Array)((Array)p_a.occurrences[0])[1])[0] == 0 &&
(int)((Array)((Array)p_b.occurrences[0])[1])[0] == 0) {
if (p_a.word.substr(0, 1) != p_b.word.substr(0, 1)) {
return p_a.word.substr(0, 1) != p_a.word.substr(0, 1).to_lower();
}
}
}

int min_size = p_a.occurrences.size() < p_b.occurrences.size() ? p_a.occurrences.size() : p_b.occurrences.size();

for (int i = 0; i < min_size; i++) {
if (((Array)((Array)p_a.occurrences[i])[1])[0] < ((Array)((Array)p_b.occurrences[i])[1])[0])
return true;
else if (((Array)((Array)p_b.occurrences[i])[1])[0] < ((Array)((Array)p_a.occurrences[i])[1])[0])
return false;
else if (((Array)((Array)p_b.occurrences[i])[1])[1] < ((Array)((Array)p_a.occurrences[i])[1])[1])
return true;
else if (((Array)((Array)p_a.occurrences[i])[1])[1] < ((Array)((Array)p_b.occurrences[i])[1])[1])
return false;
}

return p_a.word.length() < p_b.word.length();
}
};

enum MenuItems {
MENU_CUT,
MENU_COPY,
Expand Down