Add multi caret support to Editor

This commit is contained in:
Paulb23 2022-06-08 22:41:38 +01:00
parent e9180241e8
commit 0cbe176ce6
5 changed files with 456 additions and 255 deletions

View file

@ -55,6 +55,7 @@ void GotoLineDialog::ok_pressed() {
if (get_line() < 1 || get_line() > text_editor->get_line_count()) { if (get_line() < 1 || get_line() > text_editor->get_line_count()) {
return; return;
} }
text_editor->remove_secondary_carets();
text_editor->unfold_line(get_line() - 1); text_editor->unfold_line(get_line() - 1);
text_editor->set_caret_line(get_line() - 1); text_editor->set_caret_line(get_line() - 1);
hide(); hide();
@ -149,7 +150,7 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
text_editor->unfold_line(pos.y); text_editor->unfold_line(pos.y);
text_editor->set_caret_line(pos.y, false); text_editor->set_caret_line(pos.y, false);
text_editor->set_caret_column(pos.x + text.length(), false); text_editor->set_caret_column(pos.x + text.length(), false);
text_editor->center_viewport_to_caret(); text_editor->center_viewport_to_caret(0);
text_editor->select(pos.y, pos.x, pos.y, pos.x + text.length()); text_editor->select(pos.y, pos.x, pos.y, pos.x + text.length());
line_col_changed_for_result = true; line_col_changed_for_result = true;
@ -176,11 +177,11 @@ bool FindReplaceBar::_search(uint32_t p_flags, int p_from_line, int p_from_col)
} }
void FindReplaceBar::_replace() { void FindReplaceBar::_replace() {
bool selection_enabled = text_editor->has_selection(); bool selection_enabled = text_editor->has_selection(0);
Point2i selection_begin, selection_end; Point2i selection_begin, selection_end;
if (selection_enabled) { if (selection_enabled) {
selection_begin = Point2i(text_editor->get_selection_from_line(), text_editor->get_selection_from_column()); selection_begin = Point2i(text_editor->get_selection_from_line(0), text_editor->get_selection_from_column(0));
selection_end = Point2i(text_editor->get_selection_to_line(), text_editor->get_selection_to_column()); selection_end = Point2i(text_editor->get_selection_to_line(0), text_editor->get_selection_to_column(0));
} }
String replace_text = get_replace_text(); String replace_text = get_replace_text();
@ -188,25 +189,25 @@ void FindReplaceBar::_replace() {
text_editor->begin_complex_operation(); text_editor->begin_complex_operation();
if (selection_enabled && is_selection_only()) { // To restrict search_current() to selected region if (selection_enabled && is_selection_only()) { // To restrict search_current() to selected region
text_editor->set_caret_line(selection_begin.width); text_editor->set_caret_line(selection_begin.width, false, true, 0, 0);
text_editor->set_caret_column(selection_begin.height); text_editor->set_caret_column(selection_begin.height, true, 0);
} }
if (search_current()) { if (search_current()) {
text_editor->unfold_line(result_line); text_editor->unfold_line(result_line);
text_editor->select(result_line, result_col, result_line, result_col + search_text_len); text_editor->select(result_line, result_col, result_line, result_col + search_text_len, 0);
if (selection_enabled && is_selection_only()) { if (selection_enabled && is_selection_only()) {
Point2i match_from(result_line, result_col); Point2i match_from(result_line, result_col);
Point2i match_to(result_line, result_col + search_text_len); Point2i match_to(result_line, result_col + search_text_len);
if (!(match_from < selection_begin || match_to > selection_end)) { if (!(match_from < selection_begin || match_to > selection_end)) {
text_editor->insert_text_at_caret(replace_text); text_editor->insert_text_at_caret(replace_text, 0);
if (match_to.x == selection_end.x) { // Adjust selection bounds if necessary if (match_to.x == selection_end.x) { // Adjust selection bounds if necessary
selection_end.y += replace_text.length() - search_text_len; selection_end.y += replace_text.length() - search_text_len;
} }
} }
} else { } else {
text_editor->insert_text_at_caret(replace_text); text_editor->insert_text_at_caret(replace_text, 0);
} }
} }
text_editor->end_complex_operation(); text_editor->end_complex_operation();
@ -216,29 +217,29 @@ void FindReplaceBar::_replace() {
if (selection_enabled && is_selection_only()) { if (selection_enabled && is_selection_only()) {
// Reselect in order to keep 'Replace' restricted to selection // Reselect in order to keep 'Replace' restricted to selection
text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y); text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y, 0);
} else { } else {
text_editor->deselect(); text_editor->deselect(0);
} }
} }
void FindReplaceBar::_replace_all() { void FindReplaceBar::_replace_all() {
text_editor->disconnect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed)); text_editor->disconnect("text_changed", callable_mp(this, &FindReplaceBar::_editor_text_changed));
// Line as x so it gets priority in comparison, column as y. // Line as x so it gets priority in comparison, column as y.
Point2i orig_cursor(text_editor->get_caret_line(), text_editor->get_caret_column()); Point2i orig_cursor(text_editor->get_caret_line(0), text_editor->get_caret_column(0));
Point2i prev_match = Point2(-1, -1); Point2i prev_match = Point2(-1, -1);
bool selection_enabled = text_editor->has_selection(); bool selection_enabled = text_editor->has_selection(0);
Point2i selection_begin, selection_end; Point2i selection_begin, selection_end;
if (selection_enabled) { if (selection_enabled) {
selection_begin = Point2i(text_editor->get_selection_from_line(), text_editor->get_selection_from_column()); selection_begin = Point2i(text_editor->get_selection_from_line(0), text_editor->get_selection_from_column(0));
selection_end = Point2i(text_editor->get_selection_to_line(), text_editor->get_selection_to_column()); selection_end = Point2i(text_editor->get_selection_to_line(0), text_editor->get_selection_to_column(0));
} }
int vsval = text_editor->get_v_scroll(); int vsval = text_editor->get_v_scroll();
text_editor->set_caret_line(0); text_editor->set_caret_line(0, false, true, 0, 0);
text_editor->set_caret_column(0); text_editor->set_caret_column(0, true, 0);
String replace_text = get_replace_text(); String replace_text = get_replace_text();
int search_text_len = get_search_text().length(); int search_text_len = get_search_text().length();
@ -250,8 +251,8 @@ void FindReplaceBar::_replace_all() {
text_editor->begin_complex_operation(); text_editor->begin_complex_operation();
if (selection_enabled && is_selection_only()) { if (selection_enabled && is_selection_only()) {
text_editor->set_caret_line(selection_begin.width); text_editor->set_caret_line(selection_begin.width, false, true, 0, 0);
text_editor->set_caret_column(selection_begin.height); text_editor->set_caret_column(selection_begin.height, true, 0);
} }
if (search_current()) { if (search_current()) {
do { do {
@ -266,7 +267,7 @@ void FindReplaceBar::_replace_all() {
prev_match = Point2i(result_line, result_col + replace_text.length()); prev_match = Point2i(result_line, result_col + replace_text.length());
text_editor->unfold_line(result_line); text_editor->unfold_line(result_line);
text_editor->select(result_line, result_col, result_line, match_to.y); text_editor->select(result_line, result_col, result_line, match_to.y, 0);
if (selection_enabled && is_selection_only()) { if (selection_enabled && is_selection_only()) {
if (match_from < selection_begin || match_to > selection_end) { if (match_from < selection_begin || match_to > selection_end) {
@ -274,14 +275,14 @@ void FindReplaceBar::_replace_all() {
} }
// Replace but adjust selection bounds. // Replace but adjust selection bounds.
text_editor->insert_text_at_caret(replace_text); text_editor->insert_text_at_caret(replace_text, 0);
if (match_to.x == selection_end.x) { if (match_to.x == selection_end.x) {
selection_end.y += replace_text.length() - search_text_len; selection_end.y += replace_text.length() - search_text_len;
} }
} else { } else {
// Just replace. // Just replace.
text_editor->insert_text_at_caret(replace_text); text_editor->insert_text_at_caret(replace_text, 0);
} }
rc++; rc++;
@ -293,14 +294,14 @@ void FindReplaceBar::_replace_all() {
replace_all_mode = false; replace_all_mode = false;
// Restore editor state (selection, cursor, scroll). // Restore editor state (selection, cursor, scroll).
text_editor->set_caret_line(orig_cursor.x); text_editor->set_caret_line(orig_cursor.x, false, true, 0, 0);
text_editor->set_caret_column(orig_cursor.y); text_editor->set_caret_column(orig_cursor.y, true, 0);
if (selection_enabled && is_selection_only()) { if (selection_enabled && is_selection_only()) {
// Reselect. // Reselect.
text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y); text_editor->select(selection_begin.x, selection_begin.y, selection_end.x, selection_end.y, 0);
} else { } else {
text_editor->deselect(); text_editor->deselect(0);
} }
text_editor->set_v_scroll(vsval); text_editor->set_v_scroll(vsval);
@ -314,10 +315,10 @@ void FindReplaceBar::_replace_all() {
} }
void FindReplaceBar::_get_search_from(int &r_line, int &r_col) { void FindReplaceBar::_get_search_from(int &r_line, int &r_col) {
r_line = text_editor->get_caret_line(); r_line = text_editor->get_caret_line(0);
r_col = text_editor->get_caret_column(); r_col = text_editor->get_caret_column(0);
if (text_editor->has_selection() && is_selection_only()) { if (text_editor->has_selection(0) && is_selection_only()) {
return; return;
} }
@ -434,7 +435,7 @@ bool FindReplaceBar::search_prev() {
int line, col; int line, col;
_get_search_from(line, col); _get_search_from(line, col);
if (text_editor->has_selection()) { if (text_editor->has_selection(0)) {
col--; // Skip currently selected word. col--; // Skip currently selected word.
} }
@ -512,8 +513,8 @@ void FindReplaceBar::_show_search(bool p_focus_replace, bool p_show_only) {
search_text->call_deferred(SNAME("grab_focus")); search_text->call_deferred(SNAME("grab_focus"));
} }
if (text_editor->has_selection() && !selection_only->is_pressed()) { if (text_editor->has_selection(0) && !selection_only->is_pressed()) {
search_text->set_text(text_editor->get_selected_text()); search_text->set_text(text_editor->get_selected_text(0));
} }
if (!get_search_text().is_empty()) { if (!get_search_text().is_empty()) {
@ -548,9 +549,9 @@ void FindReplaceBar::popup_replace() {
hbc_option_replace->show(); hbc_option_replace->show();
} }
selection_only->set_pressed((text_editor->has_selection() && text_editor->get_selection_from_line() < text_editor->get_selection_to_line())); selection_only->set_pressed((text_editor->has_selection(0) && text_editor->get_selection_from_line(0) < text_editor->get_selection_to_line(0)));
_show_search(is_visible() || text_editor->has_selection()); _show_search(is_visible() || text_editor->has_selection(0));
} }
void FindReplaceBar::_search_options_changed(bool p_pressed) { void FindReplaceBar::_search_options_changed(bool p_pressed) {
@ -587,7 +588,7 @@ void FindReplaceBar::_search_text_submitted(const String &p_text) {
} }
void FindReplaceBar::_replace_text_submitted(const String &p_text) { void FindReplaceBar::_replace_text_submitted(const String &p_text) {
if (selection_only->is_pressed() && text_editor->has_selection()) { if (selection_only->is_pressed() && text_editor->has_selection(0)) {
_replace_all(); _replace_all();
_hide_bar(); _hide_bar();
} else if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) { } else if (Input::get_singleton()->is_key_pressed(Key::SHIFT)) {
@ -1091,6 +1092,7 @@ void CodeTextEditor::trim_trailing_whitespace() {
} }
if (trimed_whitespace) { if (trimed_whitespace) {
text_editor->merge_overlapping_carets();
text_editor->end_complex_operation(); text_editor->end_complex_operation();
text_editor->queue_redraw(); text_editor->queue_redraw();
} }
@ -1122,8 +1124,11 @@ void CodeTextEditor::convert_indent_to_spaces() {
indent += " "; indent += " ";
} }
int cursor_line = text_editor->get_caret_line(); Vector<int> cursor_columns;
int cursor_column = text_editor->get_caret_column(); cursor_columns.resize(text_editor->get_caret_count());
for (int c = 0; c < text_editor->get_caret_count(); c++) {
cursor_columns.write[c] = text_editor->get_caret_column(c);
}
bool changed_indentation = false; bool changed_indentation = false;
for (int i = 0; i < text_editor->get_line_count(); i++) { for (int i = 0; i < text_editor->get_line_count(); i++) {
@ -1140,8 +1145,10 @@ void CodeTextEditor::convert_indent_to_spaces() {
text_editor->begin_complex_operation(); text_editor->begin_complex_operation();
changed_indentation = true; changed_indentation = true;
} }
if (cursor_line == i && cursor_column > j) { for (int c = 0; c < text_editor->get_caret_count(); c++) {
cursor_column += indent_size - 1; if (text_editor->get_caret_line(c) == i && text_editor->get_caret_column(c) > j) {
cursor_columns.write[c] += indent_size - 1;
}
} }
line = line.left(j) + indent + line.substr(j + 1); line = line.left(j) + indent + line.substr(j + 1);
} }
@ -1152,7 +1159,10 @@ void CodeTextEditor::convert_indent_to_spaces() {
} }
} }
if (changed_indentation) { if (changed_indentation) {
text_editor->set_caret_column(cursor_column); for (int c = 0; c < text_editor->get_caret_count(); c++) {
text_editor->set_caret_column(cursor_columns[c], c == 0, c);
}
text_editor->merge_overlapping_carets();
text_editor->end_complex_operation(); text_editor->end_complex_operation();
text_editor->queue_redraw(); text_editor->queue_redraw();
} }
@ -1162,8 +1172,11 @@ void CodeTextEditor::convert_indent_to_tabs() {
int indent_size = EditorSettings::get_singleton()->get("text_editor/behavior/indent/size"); int indent_size = EditorSettings::get_singleton()->get("text_editor/behavior/indent/size");
indent_size -= 1; indent_size -= 1;
int cursor_line = text_editor->get_caret_line(); Vector<int> cursor_columns;
int cursor_column = text_editor->get_caret_column(); cursor_columns.resize(text_editor->get_caret_count());
for (int c = 0; c < text_editor->get_caret_count(); c++) {
cursor_columns.write[c] = text_editor->get_caret_column(c);
}
bool changed_indentation = false; bool changed_indentation = false;
for (int i = 0; i < text_editor->get_line_count(); i++) { for (int i = 0; i < text_editor->get_line_count(); i++) {
@ -1184,8 +1197,10 @@ void CodeTextEditor::convert_indent_to_tabs() {
text_editor->begin_complex_operation(); text_editor->begin_complex_operation();
changed_indentation = true; changed_indentation = true;
} }
if (cursor_line == i && cursor_column > j) { for (int c = 0; c < text_editor->get_caret_count(); c++) {
cursor_column -= indent_size; if (text_editor->get_caret_line(c) == i && text_editor->get_caret_column(c) > j) {
cursor_columns.write[c] -= indent_size;
}
} }
line = line.left(j - indent_size) + "\t" + line.substr(j + 1); line = line.left(j - indent_size) + "\t" + line.substr(j + 1);
j = 0; j = 0;
@ -1201,7 +1216,10 @@ void CodeTextEditor::convert_indent_to_tabs() {
} }
} }
if (changed_indentation) { if (changed_indentation) {
text_editor->set_caret_column(cursor_column); for (int c = 0; c < text_editor->get_caret_count(); c++) {
text_editor->set_caret_column(cursor_columns[c], c == 0, c);
}
text_editor->merge_overlapping_carets();
text_editor->end_complex_operation(); text_editor->end_complex_operation();
text_editor->queue_redraw(); text_editor->queue_redraw();
} }
@ -1211,13 +1229,18 @@ void CodeTextEditor::convert_case(CaseStyle p_case) {
if (!text_editor->has_selection()) { if (!text_editor->has_selection()) {
return; return;
} }
text_editor->begin_complex_operation(); text_editor->begin_complex_operation();
int begin = text_editor->get_selection_from_line(); Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order();
int end = text_editor->get_selection_to_line(); for (const int &c : caret_edit_order) {
int begin_col = text_editor->get_selection_from_column(); if (!text_editor->has_selection(c)) {
int end_col = text_editor->get_selection_to_column(); continue;
}
int begin = text_editor->get_selection_from_line(c);
int end = text_editor->get_selection_to_line(c);
int begin_col = text_editor->get_selection_from_column(c);
int end_col = text_editor->get_selection_to_column(c);
for (int i = begin; i <= end; i++) { for (int i = begin; i <= end; i++) {
int len = text_editor->get_line(i).length(); int len = text_editor->get_line(i).length();
@ -1249,21 +1272,66 @@ void CodeTextEditor::convert_case(CaseStyle p_case) {
} }
text_editor->set_line(i, new_line); text_editor->set_line(i, new_line);
} }
}
text_editor->end_complex_operation(); text_editor->end_complex_operation();
} }
void CodeTextEditor::move_lines_up() { void CodeTextEditor::move_lines_up() {
text_editor->begin_complex_operation(); text_editor->begin_complex_operation();
if (text_editor->has_selection()) {
int from_line = text_editor->get_selection_from_line();
int from_col = text_editor->get_selection_from_column();
int to_line = text_editor->get_selection_to_line();
int to_column = text_editor->get_selection_to_column();
int cursor_line = text_editor->get_caret_line();
for (int i = from_line; i <= to_line; i++) { Vector<int> carets_to_remove;
int line_id = i;
int next_id = i - 1; Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order();
for (int i = 0; i < caret_edit_order.size(); i++) {
int c = caret_edit_order[i];
int cl = text_editor->get_caret_line(c);
bool swaped_caret = false;
for (int j = i + 1; j < caret_edit_order.size(); j++) {
if (text_editor->has_selection(caret_edit_order[j])) {
if (text_editor->get_selection_from_line() == cl) {
carets_to_remove.push_back(caret_edit_order[j]);
continue;
}
if (text_editor->get_selection_to_line() == cl) {
if (text_editor->has_selection(c)) {
if (text_editor->get_selection_to_line(c) != cl) {
text_editor->select(cl + 1, 0, text_editor->get_selection_to_line(c), text_editor->get_selection_to_column(c), c);
break;
}
}
carets_to_remove.push_back(c);
i = j - 1;
swaped_caret = true;
break;
}
break;
}
if (text_editor->get_caret_line(caret_edit_order[j]) == cl) {
carets_to_remove.push_back(caret_edit_order[j]);
i = j;
continue;
}
break;
}
if (swaped_caret) {
continue;
}
if (text_editor->has_selection(c)) {
int from_line = text_editor->get_selection_from_line(c);
int from_col = text_editor->get_selection_from_column(c);
int to_line = text_editor->get_selection_to_line(c);
int to_column = text_editor->get_selection_to_column(c);
int cursor_line = text_editor->get_caret_line(c);
for (int j = from_line; j <= to_line; j++) {
int line_id = j;
int next_id = j - 1;
if (line_id == 0 || next_id < 0) { if (line_id == 0 || next_id < 0) {
return; return;
@ -1273,15 +1341,15 @@ void CodeTextEditor::move_lines_up() {
text_editor->unfold_line(next_id); text_editor->unfold_line(next_id);
text_editor->swap_lines(line_id, next_id); text_editor->swap_lines(line_id, next_id);
text_editor->set_caret_line(next_id); text_editor->set_caret_line(next_id, c == 0, true, 0, c);
} }
int from_line_up = from_line > 0 ? from_line - 1 : from_line; int from_line_up = from_line > 0 ? from_line - 1 : from_line;
int to_line_up = to_line > 0 ? to_line - 1 : to_line; int to_line_up = to_line > 0 ? to_line - 1 : to_line;
int cursor_line_up = cursor_line > 0 ? cursor_line - 1 : cursor_line; int cursor_line_up = cursor_line > 0 ? cursor_line - 1 : cursor_line;
text_editor->select(from_line_up, from_col, to_line_up, to_column); text_editor->select(from_line_up, from_col, to_line_up, to_column, c);
text_editor->set_caret_line(cursor_line_up); text_editor->set_caret_line(cursor_line_up, c == 0, true, 0, c);
} else { } else {
int line_id = text_editor->get_caret_line(); int line_id = text_editor->get_caret_line(c);
int next_id = line_id - 1; int next_id = line_id - 1;
if (line_id == 0 || next_id < 0) { if (line_id == 0 || next_id < 0) {
@ -1292,148 +1360,261 @@ void CodeTextEditor::move_lines_up() {
text_editor->unfold_line(next_id); text_editor->unfold_line(next_id);
text_editor->swap_lines(line_id, next_id); text_editor->swap_lines(line_id, next_id);
text_editor->set_caret_line(next_id); text_editor->set_caret_line(next_id, c == 0, true, 0, c);
}
} }
text_editor->end_complex_operation(); text_editor->end_complex_operation();
text_editor->merge_overlapping_carets();
text_editor->queue_redraw(); text_editor->queue_redraw();
} }
void CodeTextEditor::move_lines_down() { void CodeTextEditor::move_lines_down() {
text_editor->begin_complex_operation(); text_editor->begin_complex_operation();
if (text_editor->has_selection()) {
int from_line = text_editor->get_selection_from_line();
int from_col = text_editor->get_selection_from_column();
int to_line = text_editor->get_selection_to_line();
int to_column = text_editor->get_selection_to_column();
int cursor_line = text_editor->get_caret_line();
for (int i = to_line; i >= from_line; i--) { Vector<int> carets_to_remove;
int line_id = i;
int next_id = i + 1; Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order();
for (int i = 0; i < caret_edit_order.size(); i++) {
int c = caret_edit_order[i];
int cl = text_editor->get_caret_line(c);
bool swaped_caret = false;
for (int j = i + 1; j < caret_edit_order.size(); j++) {
if (text_editor->has_selection(caret_edit_order[j])) {
if (text_editor->get_selection_from_line() == cl) {
carets_to_remove.push_back(caret_edit_order[j]);
continue;
}
if (text_editor->get_selection_to_line() == cl) {
if (text_editor->has_selection(c)) {
if (text_editor->get_selection_to_line(c) != cl) {
text_editor->select(cl + 1, 0, text_editor->get_selection_to_line(c), text_editor->get_selection_to_column(c), c);
break;
}
}
carets_to_remove.push_back(c);
i = j - 1;
swaped_caret = true;
break;
}
break;
}
if (text_editor->get_caret_line(caret_edit_order[j]) == cl) {
carets_to_remove.push_back(caret_edit_order[j]);
i = j;
continue;
}
break;
}
if (swaped_caret) {
continue;
}
if (text_editor->has_selection(c)) {
int from_line = text_editor->get_selection_from_line(c);
int from_col = text_editor->get_selection_from_column(c);
int to_line = text_editor->get_selection_to_line(c);
int to_column = text_editor->get_selection_to_column(c);
int cursor_line = text_editor->get_caret_line(c);
for (int l = to_line; l >= from_line; l--) {
int line_id = l;
int next_id = l + 1;
if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) { if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) {
return; continue;
} }
text_editor->unfold_line(line_id); text_editor->unfold_line(line_id);
text_editor->unfold_line(next_id); text_editor->unfold_line(next_id);
text_editor->swap_lines(line_id, next_id); text_editor->swap_lines(line_id, next_id);
text_editor->set_caret_line(next_id); text_editor->set_caret_line(next_id, c == 0, true, 0, c);
} }
int from_line_down = from_line < text_editor->get_line_count() ? from_line + 1 : from_line; int from_line_down = from_line < text_editor->get_line_count() ? from_line + 1 : from_line;
int to_line_down = to_line < text_editor->get_line_count() ? to_line + 1 : to_line; int to_line_down = to_line < text_editor->get_line_count() ? to_line + 1 : to_line;
int cursor_line_down = cursor_line < text_editor->get_line_count() ? cursor_line + 1 : cursor_line; int cursor_line_down = cursor_line < text_editor->get_line_count() ? cursor_line + 1 : cursor_line;
text_editor->select(from_line_down, from_col, to_line_down, to_column); text_editor->select(from_line_down, from_col, to_line_down, to_column, c);
text_editor->set_caret_line(cursor_line_down); text_editor->set_caret_line(cursor_line_down, c == 0, true, 0, c);
} else { } else {
int line_id = text_editor->get_caret_line(); int line_id = text_editor->get_caret_line(c);
int next_id = line_id + 1; int next_id = line_id + 1;
if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) { if (line_id == text_editor->get_line_count() - 1 || next_id > text_editor->get_line_count()) {
return; continue;
} }
text_editor->unfold_line(line_id); text_editor->unfold_line(line_id);
text_editor->unfold_line(next_id); text_editor->unfold_line(next_id);
text_editor->swap_lines(line_id, next_id); text_editor->swap_lines(line_id, next_id);
text_editor->set_caret_line(next_id); text_editor->set_caret_line(next_id, c == 0, true, 0, c);
} }
}
// Sort and remove backwards to preserve indexes.
carets_to_remove.sort();
for (int i = carets_to_remove.size() - 1; i >= 0; i--) {
text_editor->remove_caret(carets_to_remove[i]);
}
text_editor->merge_overlapping_carets();
text_editor->end_complex_operation(); text_editor->end_complex_operation();
text_editor->queue_redraw(); text_editor->queue_redraw();
} }
void CodeTextEditor::_delete_line(int p_line) { void CodeTextEditor::_delete_line(int p_line, int p_caret) {
// this is currently intended to be called within delete_lines() // this is currently intended to be called within delete_lines()
// so `begin_complex_operation` is omitted here // so `begin_complex_operation` is omitted here
text_editor->set_line(p_line, ""); text_editor->set_line(p_line, "");
if (p_line == 0 && text_editor->get_line_count() > 1) { if (p_line == 0 && text_editor->get_line_count() > 1) {
text_editor->set_caret_line(1); text_editor->set_caret_line(1, p_caret == 0, true, 0, p_caret);
text_editor->set_caret_column(0); text_editor->set_caret_column(0, p_caret == 0, p_caret);
} }
text_editor->backspace(); text_editor->backspace(p_caret);
if (p_line < text_editor->get_line_count()) { if (p_line < text_editor->get_line_count()) {
text_editor->unfold_line(p_line); text_editor->unfold_line(p_line);
} }
text_editor->set_caret_line(p_line); text_editor->set_caret_line(p_line, p_caret == 0, true, 0, p_caret);
} }
void CodeTextEditor::delete_lines() { void CodeTextEditor::delete_lines() {
text_editor->begin_complex_operation(); text_editor->begin_complex_operation();
if (text_editor->has_selection()) {
int to_line = text_editor->get_selection_to_line(); Vector<int> carets_to_remove;
int from_line = text_editor->get_selection_from_line();
Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order();
for (int i = 0; i < caret_edit_order.size(); i++) {
int c = caret_edit_order[i];
int cl = text_editor->get_caret_line(c);
bool swaped_caret = false;
for (int j = i + 1; j < caret_edit_order.size(); j++) {
if (text_editor->has_selection(caret_edit_order[j])) {
if (text_editor->get_selection_from_line() == cl) {
carets_to_remove.push_back(caret_edit_order[j]);
continue;
}
if (text_editor->get_selection_to_line() == cl) {
if (text_editor->has_selection(c)) {
if (text_editor->get_selection_to_line(c) != cl) {
text_editor->select(cl + 1, 0, text_editor->get_selection_to_line(c), text_editor->get_selection_to_column(c), c);
break;
}
}
carets_to_remove.push_back(c);
i = j - 1;
swaped_caret = true;
break;
}
break;
}
if (text_editor->get_caret_line(caret_edit_order[j]) == cl) {
carets_to_remove.push_back(caret_edit_order[j]);
i = j;
continue;
}
break;
}
if (swaped_caret) {
continue;
}
if (text_editor->has_selection(c)) {
int to_line = text_editor->get_selection_to_line(c);
int from_line = text_editor->get_selection_from_line(c);
int count = Math::abs(to_line - from_line) + 1; int count = Math::abs(to_line - from_line) + 1;
text_editor->set_caret_line(from_line, false); text_editor->set_caret_line(from_line, false, true, 0, c);
text_editor->deselect(); text_editor->deselect(c);
for (int i = 0; i < count; i++) { for (int j = 0; j < count; j++) {
_delete_line(from_line); _delete_line(from_line, c);
} }
} else { } else {
_delete_line(text_editor->get_caret_line()); _delete_line(text_editor->get_caret_line(c), c);
} }
}
// Sort and remove backwards to preserve indexes.
carets_to_remove.sort();
for (int i = carets_to_remove.size() - 1; i >= 0; i--) {
text_editor->remove_caret(carets_to_remove[i]);
}
text_editor->merge_overlapping_carets();
text_editor->end_complex_operation(); text_editor->end_complex_operation();
} }
void CodeTextEditor::duplicate_selection() { void CodeTextEditor::duplicate_selection() {
const int cursor_column = text_editor->get_caret_column(); text_editor->begin_complex_operation();
int from_line = text_editor->get_caret_line();
int to_line = text_editor->get_caret_line(); Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order();
for (const int &c : caret_edit_order) {
const int cursor_column = text_editor->get_caret_column(c);
int from_line = text_editor->get_caret_line(c);
int to_line = text_editor->get_caret_line(c);
int from_column = 0; int from_column = 0;
int to_column = 0; int to_column = 0;
int cursor_new_line = to_line + 1; int cursor_new_line = to_line + 1;
int cursor_new_column = text_editor->get_caret_column(); int cursor_new_column = text_editor->get_caret_column(c);
String new_text = "\n" + text_editor->get_line(from_line); String new_text = "\n" + text_editor->get_line(from_line);
bool selection_active = false; bool selection_active = false;
text_editor->set_caret_column(text_editor->get_line(from_line).length()); text_editor->set_caret_column(text_editor->get_line(from_line).length(), c == 0, c);
if (text_editor->has_selection()) { if (text_editor->has_selection(c)) {
from_column = text_editor->get_selection_from_column(); from_column = text_editor->get_selection_from_column(c);
to_column = text_editor->get_selection_to_column(); to_column = text_editor->get_selection_to_column(c);
from_line = text_editor->get_selection_from_line(); from_line = text_editor->get_selection_from_line(c);
to_line = text_editor->get_selection_to_line(); to_line = text_editor->get_selection_to_line(c);
cursor_new_line = to_line + text_editor->get_caret_line() - from_line; cursor_new_line = to_line + text_editor->get_caret_line(c) - from_line;
cursor_new_column = to_column == cursor_column ? 2 * to_column - from_column : to_column; cursor_new_column = to_column == cursor_column ? 2 * to_column - from_column : to_column;
new_text = text_editor->get_selected_text(); new_text = text_editor->get_selected_text(c);
selection_active = true; selection_active = true;
text_editor->set_caret_line(to_line); text_editor->set_caret_line(to_line, c == 0, true, 0, c);
text_editor->set_caret_column(to_column); text_editor->set_caret_column(to_column, c == 0, c);
} }
text_editor->begin_complex_operation();
for (int i = from_line; i <= to_line; i++) { for (int i = from_line; i <= to_line; i++) {
text_editor->unfold_line(i); text_editor->unfold_line(i);
} }
text_editor->deselect(); text_editor->deselect(c);
text_editor->insert_text_at_caret(new_text); text_editor->insert_text_at_caret(new_text, c);
text_editor->set_caret_line(cursor_new_line); text_editor->set_caret_line(cursor_new_line, c == 0, true, 0, c);
text_editor->set_caret_column(cursor_new_column); text_editor->set_caret_column(cursor_new_column, c == 0, c);
if (selection_active) { if (selection_active) {
text_editor->select(to_line, to_column, 2 * to_line - from_line, to_line == from_line ? 2 * to_column - from_column : to_column); text_editor->select(to_line, to_column, 2 * to_line - from_line, to_line == from_line ? 2 * to_column - from_column : to_column, c);
} }
}
text_editor->merge_overlapping_carets();
text_editor->end_complex_operation(); text_editor->end_complex_operation();
text_editor->queue_redraw(); text_editor->queue_redraw();
} }
void CodeTextEditor::toggle_inline_comment(const String &delimiter) { void CodeTextEditor::toggle_inline_comment(const String &delimiter) {
text_editor->begin_complex_operation(); text_editor->begin_complex_operation();
if (text_editor->has_selection()) {
int begin = text_editor->get_selection_from_line(); Vector<int> caret_edit_order = text_editor->get_caret_index_edit_order();
int end = text_editor->get_selection_to_line(); for (const int &c : caret_edit_order) {
if (text_editor->has_selection(c)) {
int begin = text_editor->get_selection_from_line(c);
int end = text_editor->get_selection_to_line(c);
// End of selection ends on the first column of the last line, ignore it. // End of selection ends on the first column of the last line, ignore it.
if (text_editor->get_selection_to_column() == 0) { if (text_editor->get_selection_to_column(c) == 0) {
end -= 1; end -= 1;
} }
int col_to = text_editor->get_selection_to_column(); int col_to = text_editor->get_selection_to_column(c);
int cursor_pos = text_editor->get_caret_column(); int cursor_pos = text_editor->get_caret_column(c);
// Check if all lines in the selected block are commented. // Check if all lines in the selected block are commented.
bool is_commented = true; bool is_commented = true;
@ -1460,29 +1641,29 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) {
// Adjust selection & cursor position. // Adjust selection & cursor position.
int offset = (is_commented ? -1 : 1) * delimiter.length(); int offset = (is_commented ? -1 : 1) * delimiter.length();
int col_from = text_editor->get_selection_from_column() > 0 ? text_editor->get_selection_from_column() + offset : 0; int col_from = text_editor->get_selection_from_column(c) > 0 ? text_editor->get_selection_from_column(c) + offset : 0;
if (is_commented && text_editor->get_caret_column() == text_editor->get_line(text_editor->get_caret_line()).length() + 1) { if (is_commented && text_editor->get_caret_column(c) == text_editor->get_line(text_editor->get_caret_line(c)).length() + 1) {
cursor_pos += 1; cursor_pos += 1;
} }
if (text_editor->get_selection_to_column() != 0 && col_to != text_editor->get_line(text_editor->get_selection_to_line()).length() + 1) { if (text_editor->get_selection_to_column(c) != 0 && col_to != text_editor->get_line(text_editor->get_selection_to_line(c)).length() + 1) {
col_to += offset; col_to += offset;
} }
if (text_editor->get_caret_column() != 0) { if (text_editor->get_caret_column(c) != 0) {
cursor_pos += offset; cursor_pos += offset;
} }
text_editor->select(begin, col_from, text_editor->get_selection_to_line(), col_to); text_editor->select(begin, col_from, text_editor->get_selection_to_line(c), col_to, c);
text_editor->set_caret_column(cursor_pos); text_editor->set_caret_column(cursor_pos, c == 0, c);
} else { } else {
int begin = text_editor->get_caret_line(); int begin = text_editor->get_caret_line(c);
String line_text = text_editor->get_line(begin); String line_text = text_editor->get_line(begin);
int delimiter_length = delimiter.length(); int delimiter_length = delimiter.length();
int col = text_editor->get_caret_column(); int col = text_editor->get_caret_column(c);
if (line_text.begins_with(delimiter)) { if (line_text.begins_with(delimiter)) {
line_text = line_text.substr(delimiter_length, line_text.length()); line_text = line_text.substr(delimiter_length, line_text.length());
col -= delimiter_length; col -= delimiter_length;
@ -1492,19 +1673,23 @@ void CodeTextEditor::toggle_inline_comment(const String &delimiter) {
} }
text_editor->set_line(begin, line_text); text_editor->set_line(begin, line_text);
text_editor->set_caret_column(col); text_editor->set_caret_column(col, c == 0, c);
} }
}
text_editor->merge_overlapping_carets();
text_editor->end_complex_operation(); text_editor->end_complex_operation();
text_editor->queue_redraw(); text_editor->queue_redraw();
} }
void CodeTextEditor::goto_line(int p_line) { void CodeTextEditor::goto_line(int p_line) {
text_editor->remove_secondary_carets();
text_editor->deselect(); text_editor->deselect();
text_editor->unfold_line(p_line); text_editor->unfold_line(p_line);
text_editor->call_deferred(SNAME("set_caret_line"), p_line); text_editor->call_deferred(SNAME("set_caret_line"), p_line);
} }
void CodeTextEditor::goto_line_selection(int p_line, int p_begin, int p_end) { void CodeTextEditor::goto_line_selection(int p_line, int p_begin, int p_end) {
text_editor->remove_secondary_carets();
text_editor->unfold_line(p_line); text_editor->unfold_line(p_line);
text_editor->call_deferred(SNAME("set_caret_line"), p_line); text_editor->call_deferred(SNAME("set_caret_line"), p_line);
text_editor->call_deferred(SNAME("set_caret_column"), p_begin); text_editor->call_deferred(SNAME("set_caret_column"), p_begin);
@ -1608,6 +1793,7 @@ void CodeTextEditor::goto_error() {
if (text_editor->get_line_count() != error_line) { if (text_editor->get_line_count() != error_line) {
text_editor->unfold_line(error_line); text_editor->unfold_line(error_line);
} }
text_editor->remove_secondary_carets();
text_editor->set_caret_line(error_line); text_editor->set_caret_line(error_line);
text_editor->set_caret_column(error_column); text_editor->set_caret_column(error_column);
text_editor->center_viewport_to_caret(); text_editor->center_viewport_to_caret();
@ -1784,9 +1970,11 @@ void CodeTextEditor::set_warning_count(int p_warning_count) {
} }
void CodeTextEditor::toggle_bookmark() { void CodeTextEditor::toggle_bookmark() {
int line = text_editor->get_caret_line(); for (int i = 0; i < text_editor->get_caret_count(); i++) {
int line = text_editor->get_caret_line(i);
text_editor->set_line_as_bookmarked(line, !text_editor->is_line_bookmarked(line)); text_editor->set_line_as_bookmarked(line, !text_editor->is_line_bookmarked(line));
} }
}
void CodeTextEditor::goto_next_bookmark() { void CodeTextEditor::goto_next_bookmark() {
PackedInt32Array bmarks = text_editor->get_bookmarked_lines(); PackedInt32Array bmarks = text_editor->get_bookmarked_lines();
@ -1794,6 +1982,7 @@ void CodeTextEditor::goto_next_bookmark() {
return; return;
} }
text_editor->remove_secondary_carets();
int line = text_editor->get_caret_line(); int line = text_editor->get_caret_line();
if (line >= (int)bmarks[bmarks.size() - 1]) { if (line >= (int)bmarks[bmarks.size() - 1]) {
text_editor->unfold_line(bmarks[0]); text_editor->unfold_line(bmarks[0]);
@ -1818,6 +2007,7 @@ void CodeTextEditor::goto_prev_bookmark() {
return; return;
} }
text_editor->remove_secondary_carets();
int line = text_editor->get_caret_line(); int line = text_editor->get_caret_line();
if (line <= (int)bmarks[0]) { if (line <= (int)bmarks[0]) {
text_editor->unfold_line(bmarks[bmarks.size() - 1]); text_editor->unfold_line(bmarks[bmarks.size() - 1]);

View file

@ -197,7 +197,7 @@ class CodeTextEditor : public VBoxContainer {
void _update_status_bar_theme(); void _update_status_bar_theme();
void _delete_line(int p_line); void _delete_line(int p_line, int p_caret);
void _toggle_scripts_pressed(); void _toggle_scripts_pressed();
protected: protected:

View file

@ -267,6 +267,7 @@ void ScriptTextEditor::_warning_clicked(Variant p_line) {
void ScriptTextEditor::_error_clicked(Variant p_line) { void ScriptTextEditor::_error_clicked(Variant p_line) {
if (p_line.get_type() == Variant::INT) { if (p_line.get_type() == Variant::INT) {
code_editor->get_text_editor()->remove_secondary_carets();
code_editor->get_text_editor()->set_caret_line(p_line.operator int64_t()); code_editor->get_text_editor()->set_caret_line(p_line.operator int64_t());
} }
} }
@ -295,6 +296,7 @@ void ScriptTextEditor::reload_text() {
void ScriptTextEditor::add_callback(const String &p_function, PackedStringArray p_args) { void ScriptTextEditor::add_callback(const String &p_function, PackedStringArray p_args) {
String code = code_editor->get_text_editor()->get_text(); String code = code_editor->get_text_editor()->get_text();
int pos = script->get_language()->find_function(p_function, code); int pos = script->get_language()->find_function(p_function, code);
code_editor->get_text_editor()->remove_secondary_carets();
if (pos == -1) { if (pos == -1) {
//does not exist //does not exist
code_editor->get_text_editor()->deselect(); code_editor->get_text_editor()->deselect();
@ -1363,6 +1365,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
return; return;
} }
tx->remove_secondary_carets();
int line = tx->get_caret_line(); int line = tx->get_caret_line();
// wrap around // wrap around
@ -1389,6 +1392,7 @@ void ScriptTextEditor::_edit_option(int p_op) {
return; return;
} }
tx->remove_secondary_carets();
int line = tx->get_caret_line(); int line = tx->get_caret_line();
// wrap around // wrap around
if (line <= (int)bpoints[0]) { if (line <= (int)bpoints[0]) {
@ -1409,21 +1413,21 @@ void ScriptTextEditor::_edit_option(int p_op) {
} break; } break;
case HELP_CONTEXTUAL: { case HELP_CONTEXTUAL: {
String text = tx->get_selected_text(); String text = tx->get_selected_text(0);
if (text.is_empty()) { if (text.is_empty()) {
text = tx->get_word_under_caret(); text = tx->get_word_under_caret(0);
} }
if (!text.is_empty()) { if (!text.is_empty()) {
emit_signal(SNAME("request_help"), text); emit_signal(SNAME("request_help"), text);
} }
} break; } break;
case LOOKUP_SYMBOL: { case LOOKUP_SYMBOL: {
String text = tx->get_word_under_caret(); String text = tx->get_word_under_caret(0);
if (text.is_empty()) { if (text.is_empty()) {
text = tx->get_selected_text(); text = tx->get_selected_text(0);
} }
if (!text.is_empty()) { if (!text.is_empty()) {
_lookup_symbol(text, tx->get_caret_line(), tx->get_caret_column()); _lookup_symbol(text, tx->get_caret_line(0), tx->get_caret_column(0));
} }
} break; } break;
} }
@ -1601,6 +1605,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
int col = pos.x; int col = pos.x;
if (d.has("type") && String(d["type"]) == "resource") { if (d.has("type") && String(d["type"]) == "resource") {
te->remove_secondary_carets();
Ref<Resource> res = d["resource"]; Ref<Resource> res = d["resource"];
if (!res.is_valid()) { if (!res.is_valid()) {
return; return;
@ -1618,6 +1623,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
} }
if (d.has("type") && (String(d["type"]) == "files" || String(d["type"]) == "files_and_dirs")) { if (d.has("type") && (String(d["type"]) == "files" || String(d["type"]) == "files_and_dirs")) {
te->remove_secondary_carets();
Array files = d["files"]; Array files = d["files"];
String text_to_drop; String text_to_drop;
@ -1641,6 +1647,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
} }
if (d.has("type") && String(d["type"]) == "nodes") { if (d.has("type") && String(d["type"]) == "nodes") {
te->remove_secondary_carets();
Node *scene_root = get_tree()->get_edited_scene_root(); Node *scene_root = get_tree()->get_edited_scene_root();
if (!scene_root) { if (!scene_root) {
EditorNode::get_singleton()->show_warning(TTR("Can't drop nodes without an open scene.")); EditorNode::get_singleton()->show_warning(TTR("Can't drop nodes without an open scene."));
@ -1725,6 +1732,7 @@ void ScriptTextEditor::drop_data_fw(const Point2 &p_point, const Variant &p_data
} }
if (d.has("type") && String(d["type"]) == "obj_property") { if (d.has("type") && String(d["type"]) == "obj_property") {
te->remove_secondary_carets();
const String text_to_drop = String(d["property"]).c_escape().quote(quote_style); const String text_to_drop = String(d["property"]).c_escape().quote(quote_style);
te->set_caret_line(row); te->set_caret_line(row);
@ -1745,8 +1753,8 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
local_pos = mb->get_global_position() - tx->get_global_position(); local_pos = mb->get_global_position() - tx->get_global_position();
create_menu = true; create_menu = true;
} else if (k.is_valid() && k->is_action("ui_menu", true)) { } else if (k.is_valid() && k->is_action("ui_menu", true)) {
tx->adjust_viewport_to_caret(); tx->adjust_viewport_to_caret(0);
local_pos = tx->get_caret_draw_pos(); local_pos = tx->get_caret_draw_pos(0);
create_menu = true; create_menu = true;
} }
@ -1757,6 +1765,7 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
tx->set_move_caret_on_right_click_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/move_caret_on_right_click")); tx->set_move_caret_on_right_click_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/move_caret_on_right_click"));
if (tx->is_move_caret_on_right_click_enabled()) { if (tx->is_move_caret_on_right_click_enabled()) {
tx->remove_secondary_carets();
if (tx->has_selection()) { if (tx->has_selection()) {
int from_line = tx->get_selection_from_line(); int from_line = tx->get_selection_from_line();
int to_line = tx->get_selection_to_line(); int to_line = tx->get_selection_to_line();
@ -1776,10 +1785,10 @@ void ScriptTextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
String word_at_pos = tx->get_word_at_pos(local_pos); String word_at_pos = tx->get_word_at_pos(local_pos);
if (word_at_pos.is_empty()) { if (word_at_pos.is_empty()) {
word_at_pos = tx->get_word_under_caret(); word_at_pos = tx->get_word_under_caret(0);
} }
if (word_at_pos.is_empty()) { if (word_at_pos.is_empty()) {
word_at_pos = tx->get_selected_text(); word_at_pos = tx->get_selected_text(0);
} }
bool has_color = (word_at_pos == "Color"); bool has_color = (word_at_pos == "Color");

View file

@ -441,6 +441,7 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
bool is_folded = tx->is_line_folded(row); bool is_folded = tx->is_line_folded(row);
if (tx->is_move_caret_on_right_click_enabled()) { if (tx->is_move_caret_on_right_click_enabled()) {
tx->remove_secondary_carets();
if (tx->has_selection()) { if (tx->has_selection()) {
int from_line = tx->get_selection_from_line(); int from_line = tx->get_selection_from_line();
int to_line = tx->get_selection_to_line(); int to_line = tx->get_selection_to_line();
@ -467,9 +468,9 @@ void TextEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
Ref<InputEventKey> k = ev; Ref<InputEventKey> k = ev;
if (k.is_valid() && k->is_pressed() && k->is_action("ui_menu", true)) { if (k.is_valid() && k->is_pressed() && k->is_action("ui_menu", true)) {
CodeEdit *tx = code_editor->get_text_editor(); CodeEdit *tx = code_editor->get_text_editor();
int line = tx->get_caret_line(); int line = tx->get_caret_line(0);
tx->adjust_viewport_to_caret(); tx->adjust_viewport_to_caret(0);
_make_context_menu(tx->has_selection(), tx->can_fold_line(line), tx->is_line_folded(line), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->get_caret_draw_pos())); _make_context_menu(tx->has_selection(0), tx->can_fold_line(line), tx->is_line_folded(line), (get_global_transform().inverse() * tx->get_global_transform()).xform(tx->get_caret_draw_pos(0)));
context_menu->grab_focus(); context_menu->grab_focus();
} }
} }

View file

@ -954,6 +954,7 @@ void TextShaderEditor::_text_edit_gui_input(const Ref<InputEvent> &ev) {
tx->set_move_caret_on_right_click_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/move_caret_on_right_click")); tx->set_move_caret_on_right_click_enabled(EditorSettings::get_singleton()->get("text_editor/behavior/navigation/move_caret_on_right_click"));
if (tx->is_move_caret_on_right_click_enabled()) { if (tx->is_move_caret_on_right_click_enabled()) {
tx->remove_secondary_carets();
if (tx->has_selection()) { if (tx->has_selection()) {
int from_line = tx->get_selection_from_line(); int from_line = tx->get_selection_from_line();
int to_line = tx->get_selection_to_line(); int to_line = tx->get_selection_to_line();