Browse Source

Merge pull request #57276 from IgorKordiukiewicz/fix-auto-brace-complete-wrap-on-selection

Rémi Verschelde 3 năm trước cách đây
mục cha
commit
74b1e77938
2 tập tin đã thay đổi với 74 bổ sung15 xóa
  1. 28 15
      scene/gui/code_edit.cpp
  2. 46 0
      tests/scene/test_code_edit.h

+ 28 - 15
scene/gui/code_edit.cpp

@@ -571,6 +571,8 @@ Control::CursorShape CodeEdit::get_cursor_shape(const Point2 &p_pos) const {
 // Overridable actions
 void CodeEdit::_handle_unicode_input_internal(const uint32_t p_unicode) {
 	bool had_selection = has_selection();
+	String selection_text = (had_selection ? get_selected_text() : "");
+
 	if (had_selection) {
 		begin_complex_operation();
 		delete_selection();
@@ -591,27 +593,38 @@ void CodeEdit::_handle_unicode_input_internal(const uint32_t p_unicode) {
 	if (auto_brace_completion_enabled) {
 		int cl = get_caret_line();
 		int cc = get_caret_column();
-		int caret_move_offset = 1;
-
-		int post_brace_pair = cc < get_line(cl).length() ? _get_auto_brace_pair_close_at_pos(cl, cc) : -1;
 
-		if (has_string_delimiter(chr) && cc > 0 && _is_char(get_line(cl)[cc - 1]) && post_brace_pair == -1) {
-			insert_text_at_caret(chr);
-		} else if (cc < get_line(cl).length() && _is_char(get_line(cl)[cc])) {
-			insert_text_at_caret(chr);
-		} else if (post_brace_pair != -1 && auto_brace_completion_pairs[post_brace_pair].close_key[0] == chr[0]) {
-			caret_move_offset = auto_brace_completion_pairs[post_brace_pair].close_key.length();
-		} else if (is_in_comment(cl, cc) != -1 || (is_in_string(cl, cc) != -1 && has_string_delimiter(chr))) {
+		if (had_selection) {
 			insert_text_at_caret(chr);
+
+			String close_key = get_auto_brace_completion_close_key(chr);
+			if (!close_key.is_empty()) {
+				insert_text_at_caret(selection_text + close_key);
+				set_caret_column(get_caret_column() - 1);
+			}
 		} else {
-			insert_text_at_caret(chr);
+			int caret_move_offset = 1;
+
+			int post_brace_pair = cc < get_line(cl).length() ? _get_auto_brace_pair_close_at_pos(cl, cc) : -1;
+
+			if (has_string_delimiter(chr) && cc > 0 && _is_char(get_line(cl)[cc - 1]) && post_brace_pair == -1) {
+				insert_text_at_caret(chr);
+			} else if (cc < get_line(cl).length() && _is_char(get_line(cl)[cc])) {
+				insert_text_at_caret(chr);
+			} else if (post_brace_pair != -1 && auto_brace_completion_pairs[post_brace_pair].close_key[0] == chr[0]) {
+				caret_move_offset = auto_brace_completion_pairs[post_brace_pair].close_key.length();
+			} else if (is_in_comment(cl, cc) != -1 || (is_in_string(cl, cc) != -1 && has_string_delimiter(chr))) {
+				insert_text_at_caret(chr);
+			} else {
+				insert_text_at_caret(chr);
 
-			int pre_brace_pair = _get_auto_brace_pair_open_at_pos(cl, cc + 1);
-			if (pre_brace_pair != -1) {
-				insert_text_at_caret(auto_brace_completion_pairs[pre_brace_pair].close_key);
+				int pre_brace_pair = _get_auto_brace_pair_open_at_pos(cl, cc + 1);
+				if (pre_brace_pair != -1) {
+					insert_text_at_caret(auto_brace_completion_pairs[pre_brace_pair].close_key);
+				}
 			}
+			set_caret_column(cc + caret_move_offset);
 		}
-		set_caret_column(cc + caret_move_offset);
 	} else {
 		insert_text_at_caret(chr);
 	}

+ 46 - 0
tests/scene/test_code_edit.h

@@ -2786,6 +2786,52 @@ TEST_CASE("[SceneTree][CodeEdit] completion") {
 		SEND_GUI_KEY_EVENT(code_edit, Key::APOSTROPHE);
 		SEND_GUI_KEY_EVENT(code_edit, Key::QUOTEDBL);
 		CHECK(code_edit->get_line(0) == "'\"'");
+
+		/* Wrap single line selection with brackets */
+		code_edit->clear();
+		code_edit->insert_text_at_caret("abc");
+		code_edit->select_all();
+		SEND_GUI_KEY_EVENT(code_edit, Key::BRACKETLEFT);
+		CHECK(code_edit->get_line(0) == "[abc]");
+
+		/* Caret should be after the last character of the single line selection */
+		CHECK(code_edit->get_caret_column() == 4);
+
+		/* Wrap multi line selection with brackets */
+		code_edit->clear();
+		code_edit->insert_text_at_caret("abc\nabc");
+		code_edit->select_all();
+		SEND_GUI_KEY_EVENT(code_edit, Key::BRACKETLEFT);
+		CHECK(code_edit->get_text() == "[abc\nabc]");
+
+		/* Caret should be after the last character of the multi line selection */
+		CHECK(code_edit->get_caret_line() == 1);
+		CHECK(code_edit->get_caret_column() == 3);
+
+		/* If inserted character is not a auto brace completion open key, replace selected text with the inserted character */
+		code_edit->clear();
+		code_edit->insert_text_at_caret("abc");
+		code_edit->select_all();
+		SEND_GUI_KEY_EVENT(code_edit, Key::KEY_1);
+		CHECK(code_edit->get_text() == "1");
+
+		/* If potential multichar and single brace completion is matched, it should wrap the single.  */
+		code_edit->clear();
+		code_edit->insert_text_at_caret("\'\'abc");
+		code_edit->select(0, 2, 0, 5);
+		SEND_GUI_KEY_EVENT(code_edit, Key::APOSTROPHE);
+		CHECK(code_edit->get_text() == "\'\'\'abc\'");
+
+		/* If only the potential multichar brace completion is matched, it does not wrap or complete. */
+		auto_brace_completion_pairs.erase("\'");
+		code_edit->set_auto_brace_completion_pairs(auto_brace_completion_pairs);
+		CHECK_FALSE(code_edit->has_auto_brace_completion_open_key("\'"));
+
+		code_edit->clear();
+		code_edit->insert_text_at_caret("\'\'abc");
+		code_edit->select(0, 2, 0, 5);
+		SEND_GUI_KEY_EVENT(code_edit, Key::APOSTROPHE);
+		CHECK(code_edit->get_text() == "\'\'\'");
 	}
 
 	SUBCASE("[CodeEdit] autocomplete") {