Skip to content

Add Selection and Caret for Next Occurrence of Selection#67644

Merged
clayjohn merged 1 commit into
godotengine:masterfrom
alfredbaudisch:add-selection-next-occurrence
Oct 28, 2022
Merged

Add Selection and Caret for Next Occurrence of Selection#67644
clayjohn merged 1 commit into
godotengine:masterfrom
alfredbaudisch:add-selection-next-occurrence

Conversation

@alfredbaudisch

@alfredbaudisch alfredbaudisch commented Oct 19, 2022

Copy link
Copy Markdown
Contributor

Adds the bind add_selection_for_next_occurrence to TextEdit, with CTRL+D as the default shortcut.

When the bind is performed, if a selection is currently active with the last caret in text fields, searches for the next occurrence of the selection, adds a caret and selects the next occurrence.

If no selection is currently active with the last caret in text fields, selects the word currently under the caret.

The action can be performed sequentially for all occurrences of the selection of the last caret and for all existing carets. The viewport is adjusted to the latest newly added caret.

The bind and the behaviour is similar to VS Code's "Add Selection to Next Find Match" and JetBrains' "Add Selection for Next Occurrence". It takes advantage of the multi-caret API.

The default shortcut for select_word_under_caret has been changed to ALT+G, in order to give priority to CTRL+D for add_selection_for_next_occurrence to better align with popular IDEs and editors.

Implements and closes godotengine/godot-proposals#5621

Usage

Define an Editor Shortcut for ui_text_add_selection_for_next_occurrence (default: CTRL+D):

image

Select text and keep pressing the shortcut to select the next occurrences:

multi-selection-godot3.mp4

If no selection is currently active, it selects the word under caret. If a new caret is manually added with a different selection (or no selection), the selection of the new caret is taken into consideration (like VS Code and JetBrains):

godot-multi-selection-vscode-like.mp4

It also supports manually adding a new caret to skip some occurrences. For example, in this instance I skipped some of the middle @export occurrences:

multi-selection-manually-add-cursor.mp4

Known Limitation

Currently, the selection cannot span more than one line/cannot contain line breaks. In the example video below, I tried to select:

move,
#

But it didn't work because the selection included a new line. Selecting only move, worked:

multi-selection-multi-linesno.mp4

@alfredbaudisch alfredbaudisch requested review from a team as code owners October 19, 2022 19:54
@alfredbaudisch alfredbaudisch force-pushed the add-selection-next-occurrence branch from 9608cd1 to d29ccba Compare October 19, 2022 19:55

@bruvzg bruvzg left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ctrl/Command + G will conflict with macOS action script_text_editor/find_next Meta + G (Meta and Command are the same key).

Comment thread scene/gui/text_edit.cpp Outdated
@alfredbaudisch

alfredbaudisch commented Oct 20, 2022

Copy link
Copy Markdown
Contributor Author

Ctrl/Command + G will conflict with macOS action script_text_editor/find_next Meta + G (Meta and Command are the same key).

Any suggestion @bruvzg ? I was thinking ALT+G then (at least it's the default in Rider).

@bruvzg

bruvzg commented Oct 20, 2022

Copy link
Copy Markdown
Member

Any suggestion @bruvzg ? I was thinking ALT+G then (at least it's the default in Rider).

I'm not sure. Alt + G is used to input © symbol (we already use shortcuts like Alt + 1/2/3 which is also used for input, so it might be OK, if someone will need it is always possible to rebind it on the user side).

@alfredbaudisch alfredbaudisch force-pushed the add-selection-next-occurrence branch from d29ccba to 0c1a348 Compare October 20, 2022 06:03
@alfredbaudisch alfredbaudisch requested a review from a team as a code owner October 20, 2022 06:03
@alfredbaudisch alfredbaudisch force-pushed the add-selection-next-occurrence branch 3 times, most recently from dae3e41 to caece58 Compare October 20, 2022 06:34
@coppolaemilio

Copy link
Copy Markdown
Member

If this is a keyboard shortcut that exists in JetBrains or VS Code we could use their combination for mac? Not sure where I can find that info myself at the moment 😅

@alfredbaudisch

alfredbaudisch commented Oct 20, 2022

Copy link
Copy Markdown
Contributor Author

If this is a keyboard shortcut that exists in JetBrains or VS Code we could use their combination for mac? Not sure where I can find that info myself at the moment 😅

@coppolaemilio The names in both VS Code and JetBrains:

image

@bruvzg

bruvzg commented Oct 20, 2022

Copy link
Copy Markdown
Member

VSCode on macOS use ⌘ + D for "select next match" and F3 for "find next" (Shift + F3 for previous).

@Paulb23 Paulb23 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would be tempted to swap the ui_text_select_word_under_caret and ui_text_add_selection_for_next_occurrence shortcuts to better align with other editors.

In VSCode, rather then only using the last caret, seems to check whether all carets have the same word selected before selecting the next occurrence. Though interestingly sublime and Jetbrains do only use the last caret. Not necessary need to change, but probably worth putting in the docs.

Secondly, in both VSCode and sublime, if one or more carets do not have a selection it behaves like ui_text_select_word_under_caret (without deselecting). Jetbrains has the same behaviour but only for the last caret.

Comment thread scene/gui/text_edit.cpp Outdated
Comment thread scene/gui/text_edit.cpp Outdated
Comment thread scene/gui/text_edit.cpp Outdated
Comment thread scene/gui/text_edit.cpp Outdated
Comment thread scene/gui/text_edit.cpp Outdated
Comment thread scene/gui/text_edit.cpp Outdated
Comment thread doc/classes/ProjectSettings.xml Outdated
@alfredbaudisch

alfredbaudisch commented Oct 20, 2022

Copy link
Copy Markdown
Contributor Author

Secondly, in both VSCode and sublime, if one or more carets do not have a selection it behaves like ui_text_select_word_under_caret (without deselecting). Jetbrains has the same behaviour but only for the last caret.

@Paulb23 that's a good one. I'll add the ui_text_select_word_under_caret behaviour to the feature, it makes sense, but it will be like Jetbrains. What do you think?

@Paulb23

Paulb23 commented Oct 20, 2022

Copy link
Copy Markdown
Member

I'll add the ui_text_select_word_under_caret behaviour to the feature, it makes sense, but it will be like Jetbrains. What do you think?

No strong preference, both are good. Can go with the Jetbrains approach for now as it's simpler. Can always change it later.

Adds the bind `add_selection_for_next_occurrence` to TextEdit, with CTRL+D as the default shortcut.

When the bind is performed, ff a selection is currently active with the last caret in text fields, searches for the next occurrence of the selection, adds a caret and selects the next occurrence.

If no selection is currently active with the last caret in text fields, selects the word currently under the caret.

The action can be performed sequentially for all occurrences of the selection of the last caret and for all existing carets. The viewport is adjusted to the latest newly added caret.

The bind and the behaviour is similar to VS Code's "Add Selection to Next Find Match" and JetBrains' "Add Selection for Next Occurrence". It takes advantage of the multi-caret API.

The default shortcut for `select_word_under_caret` has been changed to ALT+G, in order to give priority to CTRL+D for `add_selection_for_next_occurrence` to better align with popular IDEs and editors.
@alfredbaudisch alfredbaudisch force-pushed the add-selection-next-occurrence branch from caece58 to 7d15ecc Compare October 21, 2022 06:26
@alfredbaudisch

alfredbaudisch commented Oct 21, 2022

Copy link
Copy Markdown
Contributor Author

I'll add the ui_text_select_word_under_caret behaviour to the feature, it makes sense, but it will be like Jetbrains. What do you think?

No strong preference, both are good. Can go with the Jetbrains approach for now as it's simpler. Can always change it later.

@Paulb23 Ok, I just implemented the JetBrains behaviour (and all other changes we talked about). The PR has also been updated with an additional example video (regarding the JetBrains select word under caret behavior) and new instructions.

@Paulb23 Paulb23 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great!

@clayjohn clayjohn left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me and Paulb23 is the maintainer here, so let's go ahead and merge

@clayjohn clayjohn merged commit 0486810 into godotengine:master Oct 28, 2022
@clayjohn

Copy link
Copy Markdown
Member

Thanks!

@alfredbaudisch alfredbaudisch deleted the add-selection-next-occurrence branch October 28, 2022 09:26
@akien-mga akien-mga modified the milestones: 4.x, 4.0 Oct 31, 2022
alfredbaudisch added a commit to alfredbaudisch/godot that referenced this pull request Oct 31, 2022
Adds the bind `ui_text_remove_secondary_carets` to TextEdit, with ESC as the default shortcut.

When the bind is performed, if the TextEdit has multiple carets, `remove_secondary_carets` is called and secondary carets are removed.

This is useful when multiple selects are performed with `add_select_for_next_occurrence` godotengine#67644 or when multiple multiple carets are manually added, then it's possible to go back to a single caret with a shortcut.

Closes godotengine#67991
Streq pushed a commit to Streq/godot that referenced this pull request Feb 9, 2023
Adds the bind `ui_text_remove_secondary_carets` to TextEdit, with ESC as the default shortcut.

When the bind is performed, if the TextEdit has multiple carets, `remove_secondary_carets` is called and secondary carets are removed.

This is useful when multiple selects are performed with `add_select_for_next_occurrence` godotengine#67644 or when multiple multiple carets are manually added, then it's possible to go back to a single caret with a shortcut.

Closes godotengine#67991
@tonywei92

Copy link
Copy Markdown

How do i add the key binding? my Editor shortcut UI is a bit different from the one posted above.
image

@YuriSizov

Copy link
Copy Markdown
Contributor

my Editor shortcut UI is a bit different from the one posted above

You seem to be using Godot 3, and this PR is for Godot 4.

@PLyczkowski

Copy link
Copy Markdown

Current implementation is missing the option to select next occurrence if it's a whole word only. To activate this is VSCode you can use this option:

image

In Godot, this is ignored:

image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Selection and Caret for Next Occurrence of Selection (Select multiple occurrences of the same text and change them all at once)

10 participants