From 80f4e407b231bc19d0d2ef0aaaf9e3389f9a621d Mon Sep 17 00:00:00 2001 From: Hugo Locurcio Date: Sat, 15 May 2021 18:22:52 +0200 Subject: Add a keyboard shortcut to select the word under cursor in TextEdit This also acts as a general-purpose "deselect" shortcut since pressing it a second time will deselect text. This is available both in the script editor and in TextEdit fields in use, both in the editor and projects. The Duplicate Line script editor shortcut was moved to Ctrl + Shift + D since it conflicts with the new shortcut (Ctrl + D). The rationale for doing so is that Duplicate Line is a less commonly used action, and its behavior can be replicated by copying and pasting the current line anyway. (With no selection active, the whole line will be copied.) --- scene/gui/text_edit.cpp | 40 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) (limited to 'scene/gui/text_edit.cpp') diff --git a/scene/gui/text_edit.cpp b/scene/gui/text_edit.cpp index 053af39701..d19d95f6f4 100644 --- a/scene/gui/text_edit.cpp +++ b/scene/gui/text_edit.cpp @@ -3381,13 +3381,18 @@ void TextEdit::_gui_input(const Ref &p_gui_input) { return; } - // SELECT ALL, CUT, COPY, PASTE. + // SELECT ALL, SELECT WORD UNDER CARET, CUT, COPY, PASTE. if (k->is_action("ui_text_select_all", true)) { select_all(); accept_event(); return; } + if (k->is_action("ui_text_select_word_under_caret", true)) { + select_word_under_caret(); + accept_event(); + return; + } if (k->is_action("ui_cut", true)) { cut(); accept_event(); @@ -5149,6 +5154,39 @@ void TextEdit::select_all() { update(); } +void TextEdit::select_word_under_caret() { + if (!selecting_enabled) { + return; + } + + if (text.size() == 1 && text[0].length() == 0) { + return; + } + + if (selection.active) { + // Allow toggling selection by pressing the shortcut a second time. + // This is also usable as a general-purpose "deselect" shortcut after + // selecting anything. + deselect(); + return; + } + + int begin = 0; + int end = 0; + const Vector words = TS->shaped_text_get_word_breaks(text.get_line_data(cursor.line)->get_rid()); + for (int i = 0; i < words.size(); i++) { + if (words[i].x <= cursor.column && words[i].y >= cursor.column) { + begin = words[i].x; + end = words[i].y; + break; + } + } + + select(cursor.line, begin, cursor.line, end); + // Move the cursor to the end of the word for easier editing. + cursor_set_column(end, false); +} + void TextEdit::deselect() { selection.active = false; update(); -- cgit v1.2.3