editor: Do not run brace completion on empty text. (#2965)

Users of keyboard layout with IME complained about the peculiar
behaviour where typing in "sss" and then removing all of it left behind
one 's' and also appended a closing brace. This was not reproducible on
a buffer without language, so I've suspected that brace insertion might
be a problem here. For whatever reason when the user removes the last
character from a run that triggered IME, we receive a notification about
an empty insertion. Sadly, brace completion does not handle an empty
input properly and we erroneously insert a closing brace when deleting
the followup characters. In fact, the brace inserted is always the
closing brace for the first entry in language's config.toml 'brackets'
field (see Scheme vs Markdown). This guard also allows for the proper
removal of the first character.

Closes community tickets zed-industries/community#877
zed-industries/community#1329

Z-2869

Release Notes:
- Fixed handling of bracket completion for international keyboard
layouts that use IME. This led to Zed erroneously inserting the `}`
character while removing the first character that triggered IME.
This commit is contained in:
Piotr Osiewicz 2023-09-14 20:24:21 +02:00 committed by GitHub
parent 24698b61fd
commit 1eb74acb3e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2289,14 +2289,18 @@ impl Editor {
// bracket of any of this language's bracket pairs.
let mut bracket_pair = None;
let mut is_bracket_pair_start = false;
for (pair, enabled) in scope.brackets() {
if enabled && pair.close && pair.start.ends_with(text.as_ref()) {
bracket_pair = Some(pair.clone());
is_bracket_pair_start = true;
break;
} else if pair.end.as_str() == text.as_ref() {
bracket_pair = Some(pair.clone());
break;
if !text.is_empty() {
// `text` can be empty when an user is using IME (e.g. Chinese Wubi Simplified)
// and they are removing the character that triggered IME popup.
for (pair, enabled) in scope.brackets() {
if enabled && pair.close && pair.start.ends_with(text.as_ref()) {
bracket_pair = Some(pair.clone());
is_bracket_pair_start = true;
break;
} else if pair.end.as_str() == text.as_ref() {
bracket_pair = Some(pair.clone());
break;
}
}
}