linux/x11: Don't surround selection when XMI composing (#12632)

Thorsten Ball created

On X11 I was unable to type ä ü and other umlauts in files with
autoclose enabled, because typing ä requires me to hit

- compose key
- `"`
- `a`

When the `"` was typed, Zed would insert a matching `"` because it had a
selection around the dead-key that was inserted by the compose key.

We ran into a similar issue in #7611, but in the case of the Brazilian
keyboard, the `"` is the compose key so we didn't trigger the matching
`"`, because we didn't have a selection yet.

What this does is it fixes the issue by making the
surround-selection-with-quotes-or-brackets also depend on the autoclose
settings, which is didn't do before. This is a breaking change for users
of a Brazilian keyboard layout in which `"` cannot be used to surround
an existing selection with quotes anymore.

That _might_ be a change that users notice, but I can't think of
scenario for that where the user wants, say, `"` to be NOT autoclosed,
but work with selections. (Example is Markdown, for which autoclose for
`"` is disabled. Do we want that but allow surrounding with quotes?)

So it fixes the issue and makes the behavior slightly more consistent,
in my eyes.

Release Notes:

- Changed the behavior of surrounding selections with brackets/quotes to
also depend on the auto-close settings of the language. This is a
breaking change for users of a Brazilian keyboard layout in which `"`
cannot be used to surround an existing selection with quotes anymore.

Before:

[Screencast from 2024-06-04
11-49-51.webm](https://github.com/zed-industries/zed/assets/1185253/6bf255b5-32e9-4ba7-8b46-1e49ace2ba7c)

After:

[Screencast from 2024-06-04
11-52-19.webm](https://github.com/zed-industries/zed/assets/1185253/3cd196fc-20ba-465f-bb54-e257f7f6d9f3)

Change summary

crates/editor/src/editor.rs | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)

Detailed changes

crates/editor/src/editor.rs 🔗

@@ -2819,6 +2819,9 @@ impl Editor {
                 }
 
                 if let Some(bracket_pair) = bracket_pair {
+                    let autoclose = self.use_autoclose
+                        && snapshot.settings_at(selection.start, cx).use_autoclose;
+
                     if selection.is_empty() {
                         if is_bracket_pair_start {
                             let prefix_len = bracket_pair.start.len() - text.len();
@@ -2839,8 +2842,6 @@ impl Editor {
                                         ),
                                         &bracket_pair.start[..prefix_len],
                                     ));
-                            let autoclose = self.use_autoclose
-                                && snapshot.settings_at(selection.start, cx).use_autoclose;
                             if autoclose
                                 && following_text_allows_autoclose
                                 && preceding_text_matches_prefix
@@ -2893,7 +2894,10 @@ impl Editor {
                     }
                     // If an opening bracket is 1 character long and is typed while
                     // text is selected, then surround that text with the bracket pair.
-                    else if is_bracket_pair_start && bracket_pair.start.chars().count() == 1 {
+                    else if autoclose
+                        && is_bracket_pair_start
+                        && bracket_pair.start.chars().count() == 1
+                    {
                         edits.push((selection.start..selection.start, text.clone()));
                         edits.push((
                             selection.end..selection.end,
@@ -3016,12 +3020,7 @@ impl Editor {
                 s.select(new_selections)
             });
 
-            if brace_inserted {
-                // If we inserted a brace while composing text (i.e. typing `"` on a
-                // Brazilian keyboard), exit the composing state because most likely
-                // the user wanted to surround the selection.
-                this.unmark_text(cx);
-            } else if EditorSettings::get_global(cx).use_on_type_format {
+            if !brace_inserted && EditorSettings::get_global(cx).use_on_type_format {
                 if let Some(on_type_format_task) =
                     this.trigger_on_type_formatting(text.to_string(), cx)
                 {