enable custom separators to treat different characters as words

This commit is contained in:
Volkan Gezer 2024-05-29 13:06:43 +02:00
parent 05442e81c0
commit e60678f193
6 changed files with 157 additions and 0 deletions

View file

@ -1044,6 +1044,9 @@
The indentation style to use (tabs or spaces). The indentation style to use (tabs or spaces).
[b]Note:[/b] The [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_styleguide.html]GDScript style guide[/url] recommends using tabs for indentation. It is advised to change this setting only if you need to work on a project that currently uses spaces for indentation. [b]Note:[/b] The [url=$DOCS_URL/tutorials/scripting/gdscript/gdscript_styleguide.html]GDScript style guide[/url] recommends using tabs for indentation. It is advised to change this setting only if you need to work on a project that currently uses spaces for indentation.
</member> </member>
<member name="text_editor/behavior/navigation/custom_word_separators" type="String" setter="" getter="">
The characters to consider as word delimiters if [member text_editor/behavior/navigation/use_custom_word_separators] is [code]true[/code]. The characters should be defined without separation, for example [code]#_![/code].
</member>
<member name="text_editor/behavior/navigation/drag_and_drop_selection" type="bool" setter="" getter=""> <member name="text_editor/behavior/navigation/drag_and_drop_selection" type="bool" setter="" getter="">
If [code]true[/code], allows drag-and-dropping text in the script editor to move text. Disable this if you find yourself accidentally drag-and-dropping text in the script editor. If [code]true[/code], allows drag-and-dropping text in the script editor to move text. Disable this if you find yourself accidentally drag-and-dropping text in the script editor.
</member> </member>
@ -1063,6 +1066,12 @@
<member name="text_editor/behavior/navigation/stay_in_script_editor_on_node_selected" type="bool" setter="" getter=""> <member name="text_editor/behavior/navigation/stay_in_script_editor_on_node_selected" type="bool" setter="" getter="">
If [code]true[/code], prevents automatically switching between the Script and 2D/3D screens when selecting a node in the Scene tree dock. If [code]true[/code], prevents automatically switching between the Script and 2D/3D screens when selecting a node in the Scene tree dock.
</member> </member>
<member name="text_editor/behavior/navigation/use_custom_word_separators" type="bool" setter="" getter="">
If [code]false[/code], using [kbd]Ctrl + Left[/kbd] or [kbd]Ctrl + Right[/kbd] ([kbd]Cmd + Left[/kbd] or [kbd]Cmd + Right[/kbd] on macOS) bindings will use the behavior of [member text_editor/behavior/navigation/use_default_word_separators]. If [code]true[/code], it will also stop the caret if a character within [member text_editor/behavior/navigation/custom_word_separators] is detected. Useful for subword moving. This behavior also will be applied to the behavior of text selection.
</member>
<member name="text_editor/behavior/navigation/use_default_word_separators" type="bool" setter="" getter="">
If [code]false[/code], using [kbd]Ctrl + Left[/kbd] or [kbd]Ctrl + Right[/kbd] ([kbd]Cmd + Left[/kbd] or [kbd]Cmd + Right[/kbd] on macOS) bindings will stop moving caret only if a space or punctuation is detected. If [code]true[/code], it will also stop the caret if a character is [code]´`~$^=+|&lt;&gt;[/code], a General Punctuation, or CJK Punctuation. Useful for subword moving. This behavior also will be applied to the behavior of text selection.
</member>
<member name="text_editor/behavior/navigation/v_scroll_speed" type="int" setter="" getter=""> <member name="text_editor/behavior/navigation/v_scroll_speed" type="int" setter="" getter="">
The number of pixels to scroll with every mouse wheel increment. Higher values make the script scroll by faster when using the mouse wheel. The number of pixels to scroll with every mouse wheel increment. Higher values make the script scroll by faster when using the mouse wheel.
[b]Note:[/b] You can hold down [kbd]Alt[/kbd] while using the mouse wheel to temporarily scroll 5 times faster. [b]Note:[/b] You can hold down [kbd]Alt[/kbd] while using the mouse wheel to temporarily scroll 5 times faster.

View file

@ -1278,6 +1278,9 @@
<member name="context_menu_enabled" type="bool" setter="set_context_menu_enabled" getter="is_context_menu_enabled" default="true"> <member name="context_menu_enabled" type="bool" setter="set_context_menu_enabled" getter="is_context_menu_enabled" default="true">
If [code]true[/code], a right-click displays the context menu. If [code]true[/code], a right-click displays the context menu.
</member> </member>
<member name="custom_word_separators" type="String" setter="set_custom_word_separators" getter="get_custom_word_separators" default="&quot;&quot;">
The characters to consider as word delimiters if [member use_custom_word_separators] is [code]true[/code]. The characters should be defined without separation, for example [code]#_![/code].
</member>
<member name="deselect_on_focus_loss_enabled" type="bool" setter="set_deselect_on_focus_loss_enabled" getter="is_deselect_on_focus_loss_enabled" default="true"> <member name="deselect_on_focus_loss_enabled" type="bool" setter="set_deselect_on_focus_loss_enabled" getter="is_deselect_on_focus_loss_enabled" default="true">
If [code]true[/code], the selected text will be deselected when focus is lost. If [code]true[/code], the selected text will be deselected when focus is lost.
</member> </member>
@ -1363,6 +1366,12 @@
<member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0"> <member name="text_direction" type="int" setter="set_text_direction" getter="get_text_direction" enum="Control.TextDirection" default="0">
Base text writing direction. Base text writing direction.
</member> </member>
<member name="use_custom_word_separators" type="bool" setter="set_use_custom_word_separators" getter="is_custom_word_separators_enabled" default="false">
If [code]false[/code], using [kbd]Ctrl + Left[/kbd] or [kbd]Ctrl + Right[/kbd] ([kbd]Cmd + Left[/kbd] or [kbd]Cmd + Right[/kbd] on macOS) bindings will use the behavior of [member use_default_word_separators]. If [code]true[/code], it will also stop the caret if a character within [member custom_word_separators] is detected. Useful for subword moving. This behavior also will be applied to the behavior of text selection.
</member>
<member name="use_default_word_separators" type="bool" setter="set_use_default_word_separators" getter="is_default_word_separators_enabled" default="true">
If [code]false[/code], using [kbd]Ctrl + Left[/kbd] or [kbd]Ctrl + Right[/kbd] ([kbd]Cmd + Left[/kbd] or [kbd]Cmd + Right[/kbd] on macOS) bindings will stop moving caret only if a space or punctuation is detected. If [code]true[/code], it will also stop the caret if a character is [code]´`~$^=+|&lt;&gt;[/code], a General Punctuation, or CJK Punctuation. Useful for subword moving. This behavior also will be applied to the behavior of text selection.
</member>
<member name="virtual_keyboard_enabled" type="bool" setter="set_virtual_keyboard_enabled" getter="is_virtual_keyboard_enabled" default="true"> <member name="virtual_keyboard_enabled" type="bool" setter="set_virtual_keyboard_enabled" getter="is_virtual_keyboard_enabled" default="true">
If [code]true[/code], the native virtual keyboard is shown when focused on platforms that support it. If [code]true[/code], the native virtual keyboard is shown when focused on platforms that support it.
</member> </member>

View file

@ -1049,6 +1049,9 @@ void CodeTextEditor::update_editor_settings() {
text_editor->set_smooth_scroll_enabled(EDITOR_GET("text_editor/behavior/navigation/smooth_scrolling")); text_editor->set_smooth_scroll_enabled(EDITOR_GET("text_editor/behavior/navigation/smooth_scrolling"));
text_editor->set_v_scroll_speed(EDITOR_GET("text_editor/behavior/navigation/v_scroll_speed")); text_editor->set_v_scroll_speed(EDITOR_GET("text_editor/behavior/navigation/v_scroll_speed"));
text_editor->set_drag_and_drop_selection_enabled(EDITOR_GET("text_editor/behavior/navigation/drag_and_drop_selection")); text_editor->set_drag_and_drop_selection_enabled(EDITOR_GET("text_editor/behavior/navigation/drag_and_drop_selection"));
text_editor->set_use_default_word_separators(EDITOR_GET("text_editor/behavior/navigation/use_default_word_separators"));
text_editor->set_use_custom_word_separators(EDITOR_GET("text_editor/behavior/navigation/use_custom_word_separators"));
text_editor->set_custom_word_separators(EDITOR_GET("text_editor/behavior/navigation/custom_word_separators"));
// Behavior: Indent // Behavior: Indent
set_indent_using_spaces(EDITOR_GET("text_editor/behavior/indent/type")); set_indent_using_spaces(EDITOR_GET("text_editor/behavior/indent/type"));

View file

@ -642,6 +642,9 @@ void EditorSettings::_load_defaults(Ref<ConfigFile> p_extra_config) {
_initial_set("text_editor/behavior/navigation/drag_and_drop_selection", true); _initial_set("text_editor/behavior/navigation/drag_and_drop_selection", true);
_initial_set("text_editor/behavior/navigation/stay_in_script_editor_on_node_selected", true); _initial_set("text_editor/behavior/navigation/stay_in_script_editor_on_node_selected", true);
_initial_set("text_editor/behavior/navigation/open_script_when_connecting_signal_to_existing_method", true); _initial_set("text_editor/behavior/navigation/open_script_when_connecting_signal_to_existing_method", true);
_initial_set("text_editor/behavior/navigation/use_default_word_separators", true); // Includes ´`~$^=+|<> General punctuation and CJK punctuation.
_initial_set("text_editor/behavior/navigation/use_custom_word_separators", false);
_initial_set("text_editor/behavior/navigation/custom_word_separators", ""); // Custom word separators.
// Behavior: Indent // Behavior: Indent
EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "text_editor/behavior/indent/type", 0, "Tabs,Spaces") EDITOR_SETTING(Variant::INT, PROPERTY_HINT_ENUM, "text_editor/behavior/indent/type", 0, "Tabs,Spaces")

View file

@ -207,6 +207,8 @@ void TextEdit::Text::invalidate_cache(int p_line, int p_column, bool p_text_chan
text.write[p_line].data_buf->set_direction((TextServer::Direction)direction); text.write[p_line].data_buf->set_direction((TextServer::Direction)direction);
text.write[p_line].data_buf->set_break_flags(flags); text.write[p_line].data_buf->set_break_flags(flags);
text.write[p_line].data_buf->set_preserve_control(draw_control_chars); text.write[p_line].data_buf->set_preserve_control(draw_control_chars);
text.write[p_line].data_buf->set_custom_punctuation(get_enabled_word_separators());
if (p_ime_text.length() > 0) { if (p_ime_text.length() > 0) {
if (p_text_changed) { if (p_text_changed) {
text.write[p_line].data_buf->add_string(p_ime_text, font, font_size, language); text.write[p_line].data_buf->add_string(p_ime_text, font, font_size, language);
@ -275,6 +277,8 @@ void TextEdit::Text::invalidate_all_lines() {
} }
text.write[i].data_buf->set_width(width); text.write[i].data_buf->set_width(width);
text.write[i].data_buf->set_break_flags(flags); text.write[i].data_buf->set_break_flags(flags);
text.write[i].data_buf->set_custom_punctuation(get_enabled_word_separators());
if (tab_size_dirty) { if (tab_size_dirty) {
if (tab_size > 0) { if (tab_size > 0) {
Vector<float> tabs; Vector<float> tabs;
@ -436,6 +440,57 @@ void TextEdit::Text::move_gutters(int p_from_line, int p_to_line) {
text.write[p_from_line].gutters.resize(gutter_count); text.write[p_from_line].gutters.resize(gutter_count);
} }
void TextEdit::Text::set_use_default_word_separators(bool p_enabled) {
if (use_default_word_separators == p_enabled) {
return;
}
use_default_word_separators = p_enabled;
invalidate_all_lines();
}
void TextEdit::Text::set_use_custom_word_separators(bool p_enabled) {
if (use_custom_word_separators == p_enabled) {
return;
}
use_custom_word_separators = p_enabled;
invalidate_all_lines();
}
bool TextEdit::Text::is_default_word_separators_enabled() const {
return use_default_word_separators;
}
bool TextEdit::Text::is_custom_word_separators_enabled() const {
return use_custom_word_separators;
}
String TextEdit::Text::get_custom_word_separators() const {
return custom_word_separators;
}
String TextEdit::Text::get_default_word_separators() const {
String concat_separators = "´`~$^=+|<>";
for (char32_t ch = 0x2000; ch <= 0x206F; ++ch) { // General punctuation block.
concat_separators += ch;
}
for (char32_t ch = 0x3000; ch <= 0x303F; ++ch) { // CJK punctuation block.
concat_separators += ch;
}
return concat_separators;
}
// Get default and/or custom word separators depending on the option enabled.
String TextEdit::Text::get_enabled_word_separators() const {
String all_separators;
if (use_default_word_separators) {
all_separators += get_default_word_separators();
}
if (use_custom_word_separators) {
all_separators += get_custom_word_separators();
}
return all_separators;
}
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
/// TEXT EDIT /// /// TEXT EDIT ///
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -6267,6 +6322,44 @@ bool TextEdit::is_highlight_all_occurrences_enabled() const {
return highlight_all_occurrences; return highlight_all_occurrences;
} }
void TextEdit::set_use_default_word_separators(bool p_enabled) {
text.set_use_default_word_separators(p_enabled);
}
bool TextEdit::is_default_word_separators_enabled() const {
return text.is_default_word_separators_enabled();
}
// Set word separators. Combine default separators with custom separators if those options are enabled.
void TextEdit::set_custom_word_separators(const String &p_separators) {
text.set_custom_word_separators(p_separators);
}
void TextEdit::Text::set_custom_word_separators(const String &p_separators) {
if (custom_word_separators == p_separators) {
return;
}
custom_word_separators = p_separators;
invalidate_all_lines();
}
bool TextEdit::is_custom_word_separators_enabled() const {
return text.is_custom_word_separators_enabled();
}
String TextEdit::get_custom_word_separators() const {
return text.get_custom_word_separators();
}
// Enable or disable custom word separators.
void TextEdit::set_use_custom_word_separators(bool p_enabled) {
text.set_use_custom_word_separators(p_enabled);
}
String TextEdit::get_default_word_separators() const {
return text.get_default_word_separators();
}
void TextEdit::set_draw_control_chars(bool p_enabled) { void TextEdit::set_draw_control_chars(bool p_enabled) {
if (draw_control_chars != p_enabled) { if (draw_control_chars != p_enabled) {
draw_control_chars = p_enabled; draw_control_chars = p_enabled;
@ -6541,6 +6634,14 @@ void TextEdit::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_word_under_caret", "caret_index"), &TextEdit::get_word_under_caret, DEFVAL(-1)); ClassDB::bind_method(D_METHOD("get_word_under_caret", "caret_index"), &TextEdit::get_word_under_caret, DEFVAL(-1));
ClassDB::bind_method(D_METHOD("set_use_default_word_separators", "enabled"), &TextEdit::set_use_default_word_separators);
ClassDB::bind_method(D_METHOD("is_default_word_separators_enabled"), &TextEdit::is_default_word_separators_enabled);
ClassDB::bind_method(D_METHOD("set_use_custom_word_separators", "enabled"), &TextEdit::set_use_custom_word_separators);
ClassDB::bind_method(D_METHOD("is_custom_word_separators_enabled"), &TextEdit::is_custom_word_separators_enabled);
ClassDB::bind_method(D_METHOD("set_custom_word_separators", "custom_word_separators"), &TextEdit::set_custom_word_separators);
ClassDB::bind_method(D_METHOD("get_custom_word_separators"), &TextEdit::get_custom_word_separators);
/* Selection. */ /* Selection. */
BIND_ENUM_CONSTANT(SELECTION_MODE_NONE); BIND_ENUM_CONSTANT(SELECTION_MODE_NONE);
BIND_ENUM_CONSTANT(SELECTION_MODE_SHIFT); BIND_ENUM_CONSTANT(SELECTION_MODE_SHIFT);
@ -6764,6 +6865,10 @@ void TextEdit::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_mid_grapheme"), "set_caret_mid_grapheme_enabled", "is_caret_mid_grapheme_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_multiple"), "set_multiple_carets_enabled", "is_multiple_carets_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "caret_multiple"), "set_multiple_carets_enabled", "is_multiple_carets_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_default_word_separators"), "set_use_default_word_separators", "is_default_word_separators_enabled");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "use_custom_word_separators"), "set_use_custom_word_separators", "is_custom_word_separators_enabled");
ADD_PROPERTY(PropertyInfo(Variant::STRING, "custom_word_separators"), "set_custom_word_separators", "get_custom_word_separators");
ADD_GROUP("Highlighting", ""); ADD_GROUP("Highlighting", "");
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "syntax_highlighter", PROPERTY_HINT_RESOURCE_TYPE, "SyntaxHighlighter", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ALWAYS_DUPLICATE), "set_syntax_highlighter", "get_syntax_highlighter"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "syntax_highlighter", PROPERTY_HINT_RESOURCE_TYPE, "SyntaxHighlighter", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_ALWAYS_DUPLICATE), "set_syntax_highlighter", "get_syntax_highlighter");
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "highlight_all_occurrences"), "set_highlight_all_occurrences", "is_highlight_all_occurrences_enabled");

View file

@ -174,6 +174,9 @@ private:
TextServer::Direction direction = TextServer::DIRECTION_AUTO; TextServer::Direction direction = TextServer::DIRECTION_AUTO;
BitField<TextServer::LineBreakFlag> brk_flags = TextServer::BREAK_MANDATORY; BitField<TextServer::LineBreakFlag> brk_flags = TextServer::BREAK_MANDATORY;
bool draw_control_chars = false; bool draw_control_chars = false;
String custom_word_separators;
bool use_default_word_separators = true;
bool use_custom_word_separators = false;
int line_height = -1; int line_height = -1;
int max_width = -1; int max_width = -1;
@ -201,6 +204,18 @@ private:
int get_line_width(int p_line, int p_wrap_index = -1) const; int get_line_width(int p_line, int p_wrap_index = -1) const;
int get_max_width() const; int get_max_width() const;
void set_use_default_word_separators(bool p_enabled);
bool is_default_word_separators_enabled() const;
void set_use_custom_word_separators(bool p_enabled);
bool is_custom_word_separators_enabled() const;
void set_word_separators(const String &p_separators);
void set_custom_word_separators(const String &p_separators);
String get_enabled_word_separators() const;
String get_custom_word_separators() const;
String get_default_word_separators() const;
void set_width(float p_width); void set_width(float p_width);
float get_width() const; float get_width() const;
void set_brk_flags(BitField<TextServer::LineBreakFlag> p_flags); void set_brk_flags(BitField<TextServer::LineBreakFlag> p_flags);
@ -1068,6 +1083,19 @@ public:
Color get_font_color() const; Color get_font_color() const;
/* Behavior */
String get_default_word_separators() const;
void set_use_default_word_separators(bool p_enabled);
bool is_default_word_separators_enabled() const;
void set_custom_word_separators(const String &p_separators);
void set_use_custom_word_separators(bool p_enabled);
bool is_custom_word_separators_enabled() const;
String get_custom_word_separators() const;
/* Deprecated. */ /* Deprecated. */
#ifndef DISABLE_DEPRECATED #ifndef DISABLE_DEPRECATED
Vector<int> get_caret_index_edit_order(); Vector<int> get_caret_index_edit_order();