Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Components: Ignore user completers when reaching >= 4 words after trigger char #30589

Closed

Conversation

fullofcaffeine
Copy link
Member

@fullofcaffeine fullofcaffeine commented Apr 8, 2021

Description

Attempt at fixing #30640.

Fixes an issue introduced in #29939, where the user autocompleter enters an infinite matching loop, causing the editor to eventually slow down and become close to unusable.

The changes in #29939 are somewhat incompatible with the UX for the user autocomplete as its triggers can happen anywhere and stay on the editor even after the completion is done. Once the autocomplete finds the trigger, it runs through its matching/querying algorithm, but then doesn't know when to stop. What happens in practice is that the text after the trigger starts being considered as part of the text to match and it goes up to infinity.

The fix limits the number of words that could be matched for the user completer to 3, and bails out by on the 4th onwards. This would allow a user name with 3 words to be matched and then wouldn't try to match anymore. This is not perfect as sometimes the match will still be triggered when it shouldn't (i.e when the user already found the user and confirmed the choice), and the popup with the matched username might still be shown even after the name is found and output on the page if within the 3 words limit, but should be good enough to prevent the deadlock/slowdown.

How has this been tested?

The autocomplete search results should appear every time the search trigger is typed, i.e. the user search via @. If you continue typing after the trigger, it should stop showing the popup (if any matches) after you type 3 words. If you continue typing, you should not notice any slowdowns and the editor should be snappy.

Type of change

Bugfix.

@@ -48,6 +48,16 @@ export default {
</span>,
];
},
allowContext( before, after, textWithoutTrigger ) {
Copy link
Member Author

@fullofcaffeine fullofcaffeine Apr 8, 2021

Choose a reason for hiding this comment

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

I took the freedom to experiment a bit by turning the allowContext callback into a more general-purpose "filter" for the completer, by also allowing the textWithoutTrigger to be passed to it as the last parameter. The previous version of this changeset was clunkier as it included the logic below in the Autocomplete component, and it'd run for all completers, which was not ideal.

I'm adding to the method signature, so I'm not sure how safe this change is. I'd bet it is relatively safe. Also, you could argue that the name allowContext still somewhat fits semantically in this context. Let me know if you think a new function would be better, or if I should fall back to 1949a4a.

Copy link
Member

Choose a reason for hiding this comment

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

See #30589 (comment) where I left some more thought. I think we need something general like the maximum number of chars that gets processed and a way to fine-tune for individual completers like you propose 👍🏻

Copy link
Contributor

Choose a reason for hiding this comment

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

TBH I don't love the idea of bending allowContext to suit our needs here 😛
OTOH, I also don't love the idea of a customizable max number of chars for individual completers -- I don't think that reflects the behavior of completion as I'd imagine it.

I'll leave a top-level comment with some more discussion.

@fullofcaffeine fullofcaffeine changed the title omponents: Ignore user completers when reaching >= 4 words after trigger char Components: Ignore user completers when reaching >= 4 words after trigger char Apr 8, 2021
@noahtallen noahtallen requested a review from gziolo April 8, 2021 01:53
@github-actions
Copy link

github-actions bot commented Apr 8, 2021

Size Change: +35 B (0%)

Total Size: 1.42 MB

Filename Size Change
build/components/index.js 284 kB -2 B (0%)
build/editor/index.js 42.2 kB +37 B (0%)
ℹ️ View Unchanged
Filename Size Change
build/a11y/index.js 1.14 kB 0 B
build/annotations/index.js 3.77 kB 0 B
build/api-fetch/index.js 3.41 kB 0 B
build/autop/index.js 2.82 kB 0 B
build/blob/index.js 664 B 0 B
build/block-directory/index.js 8.62 kB 0 B
build/block-directory/style-rtl.css 1 kB 0 B
build/block-directory/style.css 1.01 kB 0 B
build/block-editor/index.js 127 kB 0 B
build/block-editor/style-rtl.css 12.4 kB 0 B
build/block-editor/style.css 12.4 kB 0 B
build/block-library/blocks/archives/editor-rtl.css 61 B 0 B
build/block-library/blocks/archives/editor.css 60 B 0 B
build/block-library/blocks/audio/editor-rtl.css 58 B 0 B
build/block-library/blocks/audio/editor.css 58 B 0 B
build/block-library/blocks/audio/style-rtl.css 112 B 0 B
build/block-library/blocks/audio/style.css 112 B 0 B
build/block-library/blocks/block/editor-rtl.css 161 B 0 B
build/block-library/blocks/block/editor.css 161 B 0 B
build/block-library/blocks/button/editor-rtl.css 475 B 0 B
build/block-library/blocks/button/editor.css 474 B 0 B
build/block-library/blocks/button/style-rtl.css 503 B 0 B
build/block-library/blocks/button/style.css 503 B 0 B
build/block-library/blocks/buttons/editor-rtl.css 315 B 0 B
build/block-library/blocks/buttons/editor.css 315 B 0 B
build/block-library/blocks/buttons/style-rtl.css 364 B 0 B
build/block-library/blocks/buttons/style.css 363 B 0 B
build/block-library/blocks/calendar/style-rtl.css 208 B 0 B
build/block-library/blocks/calendar/style.css 208 B 0 B
build/block-library/blocks/categories/editor-rtl.css 84 B 0 B
build/block-library/blocks/categories/editor.css 83 B 0 B
build/block-library/blocks/categories/style-rtl.css 79 B 0 B
build/block-library/blocks/categories/style.css 79 B 0 B
build/block-library/blocks/code/style-rtl.css 90 B 0 B
build/block-library/blocks/code/style.css 90 B 0 B
build/block-library/blocks/columns/editor-rtl.css 190 B 0 B
build/block-library/blocks/columns/editor.css 190 B 0 B
build/block-library/blocks/columns/style-rtl.css 436 B 0 B
build/block-library/blocks/columns/style.css 435 B 0 B
build/block-library/blocks/cover/editor-rtl.css 605 B 0 B
build/block-library/blocks/cover/editor.css 605 B 0 B
build/block-library/blocks/cover/style-rtl.css 1.24 kB 0 B
build/block-library/blocks/cover/style.css 1.24 kB 0 B
build/block-library/blocks/embed/editor-rtl.css 486 B 0 B
build/block-library/blocks/embed/editor.css 486 B 0 B
build/block-library/blocks/embed/style-rtl.css 401 B 0 B
build/block-library/blocks/embed/style.css 400 B 0 B
build/block-library/blocks/file/editor-rtl.css 175 B 0 B
build/block-library/blocks/file/editor.css 174 B 0 B
build/block-library/blocks/file/style-rtl.css 248 B 0 B
build/block-library/blocks/file/style.css 248 B 0 B
build/block-library/blocks/freeform/editor-rtl.css 2.45 kB 0 B
build/block-library/blocks/freeform/editor.css 2.45 kB 0 B
build/block-library/blocks/gallery/editor-rtl.css 704 B 0 B
build/block-library/blocks/gallery/editor.css 705 B 0 B
build/block-library/blocks/gallery/style-rtl.css 1.11 kB 0 B
build/block-library/blocks/gallery/style.css 1.1 kB 0 B
build/block-library/blocks/group/editor-rtl.css 160 B 0 B
build/block-library/blocks/group/editor.css 160 B 0 B
build/block-library/blocks/group/style-rtl.css 57 B 0 B
build/block-library/blocks/group/style.css 57 B 0 B
build/block-library/blocks/heading/editor-rtl.css 129 B 0 B
build/block-library/blocks/heading/editor.css 129 B 0 B
build/block-library/blocks/heading/style-rtl.css 76 B 0 B
build/block-library/blocks/heading/style.css 76 B 0 B
build/block-library/blocks/html/editor-rtl.css 281 B 0 B
build/block-library/blocks/html/editor.css 281 B 0 B
build/block-library/blocks/image/editor-rtl.css 717 B 0 B
build/block-library/blocks/image/editor.css 716 B 0 B
build/block-library/blocks/image/style-rtl.css 476 B 0 B
build/block-library/blocks/image/style.css 478 B 0 B
build/block-library/blocks/latest-comments/style-rtl.css 281 B 0 B
build/block-library/blocks/latest-comments/style.css 282 B 0 B
build/block-library/blocks/latest-posts/editor-rtl.css 137 B 0 B
build/block-library/blocks/latest-posts/editor.css 137 B 0 B
build/block-library/blocks/latest-posts/style-rtl.css 523 B 0 B
build/block-library/blocks/latest-posts/style.css 522 B 0 B
build/block-library/blocks/legacy-widget/editor-rtl.css 398 B 0 B
build/block-library/blocks/legacy-widget/editor.css 399 B 0 B
build/block-library/blocks/list/style-rtl.css 63 B 0 B
build/block-library/blocks/list/style.css 63 B 0 B
build/block-library/blocks/media-text/editor-rtl.css 191 B 0 B
build/block-library/blocks/media-text/editor.css 191 B 0 B
build/block-library/blocks/media-text/style-rtl.css 535 B 0 B
build/block-library/blocks/media-text/style.css 532 B 0 B
build/block-library/blocks/more/editor-rtl.css 434 B 0 B
build/block-library/blocks/more/editor.css 434 B 0 B
build/block-library/blocks/navigation-link/editor-rtl.css 597 B 0 B
build/block-library/blocks/navigation-link/editor.css 597 B 0 B
build/block-library/blocks/navigation-link/style-rtl.css 1.07 kB 0 B
build/block-library/blocks/navigation-link/style.css 1.07 kB 0 B
build/block-library/blocks/navigation/editor-rtl.css 1.24 kB 0 B
build/block-library/blocks/navigation/editor.css 1.24 kB 0 B
build/block-library/blocks/navigation/style-rtl.css 204 B 0 B
build/block-library/blocks/navigation/style.css 205 B 0 B
build/block-library/blocks/nextpage/editor-rtl.css 395 B 0 B
build/block-library/blocks/nextpage/editor.css 395 B 0 B
build/block-library/blocks/page-list/editor-rtl.css 170 B 0 B
build/block-library/blocks/page-list/editor.css 170 B 0 B
build/block-library/blocks/page-list/style-rtl.css 167 B 0 B
build/block-library/blocks/page-list/style.css 167 B 0 B
build/block-library/blocks/paragraph/editor-rtl.css 157 B 0 B
build/block-library/blocks/paragraph/editor.css 157 B 0 B
build/block-library/blocks/paragraph/style-rtl.css 247 B 0 B
build/block-library/blocks/paragraph/style.css 248 B 0 B
build/block-library/blocks/post-author/editor-rtl.css 209 B 0 B
build/block-library/blocks/post-author/editor.css 209 B 0 B
build/block-library/blocks/post-author/style-rtl.css 183 B 0 B
build/block-library/blocks/post-author/style.css 184 B 0 B
build/block-library/blocks/post-comments-form/style-rtl.css 250 B 0 B
build/block-library/blocks/post-comments-form/style.css 250 B 0 B
build/block-library/blocks/post-content/editor-rtl.css 139 B 0 B
build/block-library/blocks/post-content/editor.css 139 B 0 B
build/block-library/blocks/post-excerpt/editor-rtl.css 73 B 0 B
build/block-library/blocks/post-excerpt/editor.css 73 B 0 B
build/block-library/blocks/post-excerpt/style-rtl.css 69 B 0 B
build/block-library/blocks/post-excerpt/style.css 69 B 0 B
build/block-library/blocks/post-featured-image/editor-rtl.css 338 B 0 B
build/block-library/blocks/post-featured-image/editor.css 338 B 0 B
build/block-library/blocks/post-featured-image/style-rtl.css 100 B 0 B
build/block-library/blocks/post-featured-image/style.css 100 B 0 B
build/block-library/blocks/preformatted/style-rtl.css 103 B 0 B
build/block-library/blocks/preformatted/style.css 103 B 0 B
build/block-library/blocks/pullquote/editor-rtl.css 183 B 0 B
build/block-library/blocks/pullquote/editor.css 183 B 0 B
build/block-library/blocks/pullquote/style-rtl.css 318 B 0 B
build/block-library/blocks/pullquote/style.css 318 B 0 B
build/block-library/blocks/query-loop/editor-rtl.css 83 B 0 B
build/block-library/blocks/query-loop/editor.css 82 B 0 B
build/block-library/blocks/query-loop/style-rtl.css 315 B 0 B
build/block-library/blocks/query-loop/style.css 317 B 0 B
build/block-library/blocks/query-pagination-numbers/editor-rtl.css 122 B 0 B
build/block-library/blocks/query-pagination-numbers/editor.css 121 B 0 B
build/block-library/blocks/query-pagination/editor-rtl.css 270 B 0 B
build/block-library/blocks/query-pagination/editor.css 262 B 0 B
build/block-library/blocks/query-pagination/style-rtl.css 168 B 0 B
build/block-library/blocks/query-pagination/style.css 168 B 0 B
build/block-library/blocks/query-title/editor-rtl.css 86 B 0 B
build/block-library/blocks/query-title/editor.css 86 B 0 B
build/block-library/blocks/query/editor-rtl.css 795 B 0 B
build/block-library/blocks/query/editor.css 794 B 0 B
build/block-library/blocks/quote/style-rtl.css 169 B 0 B
build/block-library/blocks/quote/style.css 169 B 0 B
build/block-library/blocks/rss/editor-rtl.css 201 B 0 B
build/block-library/blocks/rss/editor.css 202 B 0 B
build/block-library/blocks/rss/style-rtl.css 290 B 0 B
build/block-library/blocks/rss/style.css 290 B 0 B
build/block-library/blocks/search/editor-rtl.css 189 B 0 B
build/block-library/blocks/search/editor.css 189 B 0 B
build/block-library/blocks/search/style-rtl.css 359 B 0 B
build/block-library/blocks/search/style.css 362 B 0 B
build/block-library/blocks/separator/editor-rtl.css 99 B 0 B
build/block-library/blocks/separator/editor.css 99 B 0 B
build/block-library/blocks/separator/style-rtl.css 251 B 0 B
build/block-library/blocks/separator/style.css 251 B 0 B
build/block-library/blocks/shortcode/editor-rtl.css 512 B 0 B
build/block-library/blocks/shortcode/editor.css 512 B 0 B
build/block-library/blocks/site-logo/editor-rtl.css 438 B 0 B
build/block-library/blocks/site-logo/editor.css 438 B 0 B
build/block-library/blocks/site-logo/style-rtl.css 150 B 0 B
build/block-library/blocks/site-logo/style.css 150 B 0 B
build/block-library/blocks/social-link/editor-rtl.css 164 B 0 B
build/block-library/blocks/social-link/editor.css 165 B 0 B
build/block-library/blocks/social-links/editor-rtl.css 776 B 0 B
build/block-library/blocks/social-links/editor.css 776 B 0 B
build/block-library/blocks/social-links/style-rtl.css 1.32 kB 0 B
build/block-library/blocks/social-links/style.css 1.33 kB 0 B
build/block-library/blocks/spacer/editor-rtl.css 308 B 0 B
build/block-library/blocks/spacer/editor.css 308 B 0 B
build/block-library/blocks/spacer/style-rtl.css 48 B 0 B
build/block-library/blocks/spacer/style.css 48 B 0 B
build/block-library/blocks/table/editor-rtl.css 478 B 0 B
build/block-library/blocks/table/editor.css 478 B 0 B
build/block-library/blocks/table/style-rtl.css 402 B 0 B
build/block-library/blocks/table/style.css 402 B 0 B
build/block-library/blocks/tag-cloud/editor-rtl.css 118 B 0 B
build/block-library/blocks/tag-cloud/editor.css 118 B 0 B
build/block-library/blocks/tag-cloud/style-rtl.css 94 B 0 B
build/block-library/blocks/tag-cloud/style.css 94 B 0 B
build/block-library/blocks/template-part/editor-rtl.css 552 B 0 B
build/block-library/blocks/template-part/editor.css 551 B 0 B
build/block-library/blocks/term-description/editor-rtl.css 90 B 0 B
build/block-library/blocks/term-description/editor.css 90 B 0 B
build/block-library/blocks/text-columns/editor-rtl.css 95 B 0 B
build/block-library/blocks/text-columns/editor.css 95 B 0 B
build/block-library/blocks/text-columns/style-rtl.css 166 B 0 B
build/block-library/blocks/text-columns/style.css 166 B 0 B
build/block-library/blocks/verse/editor-rtl.css 50 B 0 B
build/block-library/blocks/verse/editor.css 50 B 0 B
build/block-library/blocks/verse/style-rtl.css 87 B 0 B
build/block-library/blocks/verse/style.css 87 B 0 B
build/block-library/blocks/video/editor-rtl.css 504 B 0 B
build/block-library/blocks/video/editor.css 503 B 0 B
build/block-library/blocks/video/style-rtl.css 187 B 0 B
build/block-library/blocks/video/style.css 187 B 0 B
build/block-library/common-rtl.css 1.31 kB 0 B
build/block-library/common.css 1.31 kB 0 B
build/block-library/editor-rtl.css 9.74 kB 0 B
build/block-library/editor.css 9.73 kB 0 B
build/block-library/index.js 152 kB 0 B
build/block-library/reset-rtl.css 502 B 0 B
build/block-library/reset.css 503 B 0 B
build/block-library/style-rtl.css 9.4 kB 0 B
build/block-library/style.css 9.41 kB 0 B
build/block-library/theme-rtl.css 692 B 0 B
build/block-library/theme.css 693 B 0 B
build/block-serialization-default-parser/index.js 1.87 kB 0 B
build/block-serialization-spec-parser/index.js 3.06 kB 0 B
build/blocks/index.js 48.4 kB 0 B
build/components/style-rtl.css 16.3 kB 0 B
build/components/style.css 16.2 kB 0 B
build/compose/index.js 11.2 kB 0 B
build/core-data/index.js 17.1 kB 0 B
build/customize-widgets/index.js 7.27 kB 0 B
build/customize-widgets/style-rtl.css 676 B 0 B
build/customize-widgets/style.css 677 B 0 B
build/data-controls/index.js 835 B 0 B
build/data/index.js 8.88 kB 0 B
build/date/index.js 31.9 kB 0 B
build/deprecated/index.js 787 B 0 B
build/dom-ready/index.js 576 B 0 B
build/dom/index.js 5.16 kB 0 B
build/edit-navigation/index.js 17 kB 0 B
build/edit-navigation/style-rtl.css 2.86 kB 0 B
build/edit-navigation/style.css 2.86 kB 0 B
build/edit-post/classic-rtl.css 454 B 0 B
build/edit-post/classic.css 454 B 0 B
build/edit-post/index.js 307 kB 0 B
build/edit-post/style-rtl.css 6.91 kB 0 B
build/edit-post/style.css 6.9 kB 0 B
build/edit-site/index.js 28 kB 0 B
build/edit-site/style-rtl.css 4.61 kB 0 B
build/edit-site/style.css 4.61 kB 0 B
build/edit-widgets/index.js 15.7 kB 0 B
build/edit-widgets/style-rtl.css 2.98 kB 0 B
build/edit-widgets/style.css 2.98 kB 0 B
build/editor/style-rtl.css 3.93 kB 0 B
build/editor/style.css 3.92 kB 0 B
build/element/index.js 4.61 kB 0 B
build/escape-html/index.js 735 B 0 B
build/format-library/index.js 6.75 kB 0 B
build/format-library/style-rtl.css 637 B 0 B
build/format-library/style.css 639 B 0 B
build/hooks/index.js 2.28 kB 0 B
build/html-entities/index.js 622 B 0 B
build/i18n/index.js 4.01 kB 0 B
build/is-shallow-equal/index.js 699 B 0 B
build/keyboard-shortcuts/index.js 2.53 kB 0 B
build/keycodes/index.js 1.95 kB 0 B
build/list-reusable-blocks/index.js 3.19 kB 0 B
build/list-reusable-blocks/style-rtl.css 629 B 0 B
build/list-reusable-blocks/style.css 628 B 0 B
build/media-utils/index.js 5.38 kB 0 B
build/notices/index.js 1.85 kB 0 B
build/nux/index.js 3.41 kB 0 B
build/nux/style-rtl.css 731 B 0 B
build/nux/style.css 727 B 0 B
build/plugins/index.js 2.95 kB 0 B
build/primitives/index.js 1.42 kB 0 B
build/priority-queue/index.js 791 B 0 B
build/react-i18n/index.js 1.46 kB 0 B
build/redux-routine/index.js 2.84 kB 0 B
build/reusable-blocks/index.js 3.78 kB 0 B
build/reusable-blocks/style-rtl.css 225 B 0 B
build/reusable-blocks/style.css 225 B 0 B
build/rich-text/index.js 13.5 kB 0 B
build/server-side-render/index.js 2.6 kB 0 B
build/shortcode/index.js 1.7 kB 0 B
build/token-list/index.js 1.27 kB 0 B
build/url/index.js 3.02 kB 0 B
build/viewport/index.js 1.86 kB 0 B
build/warning/index.js 1.14 kB 0 B
build/wordcount/index.js 1.22 kB 0 B

compressed-size-action

…ccount the text and not only the surrounding context
@fullofcaffeine fullofcaffeine force-pushed the fix/infinite-match-for-inline-completers branch from 1cde370 to 2016c4f Compare April 8, 2021 02:21
@gziolo
Copy link
Member

gziolo commented Apr 8, 2021

The autocomplete search results should appear every time the search trigger is typed, i.e. the user search via @. If you continue typing after the trigger, it should stop showing the popup (if any matches) after you type 3 words. If you continue typing, you should not notice any slowdowns and the editor should be snappy.

My understanding was that you use esc key to stop showing suggestions to choose from or you eventually stop seeing those suggestions when you type too many words so they can't match anything.

Other than that, I see the proposed change as an interesting way to give more control over completers so we should explore that.

The changes in #29939 are somewhat incompatible with the UX for the user autocompleter, its triggers can happen anywhere and stay on the editor even after the completion is done. Once the autocomplete finds the trigger, it runs through its matching/querying algorithm, but then doesn't know when to stop. What happens in practice is that the text after the trigger starts being considered as part of the text to match and it goes up to infinity.

That's an interesting discovery. Should we make a default limit of characters to match? Or maybe better, can we count the number of characters that you typed vs the last match and stop the autocompletion at some point? E.g. the last match is one two three four f and someone types ive six – it's 7 characters longer than the last match so we can consider that there is no chance to have another match and we can close the completers.

@gziolo gziolo added [Package] Components /packages/components [Package] Editor /packages/editor [Type] Bug An existing feature does not function as intended labels Apr 8, 2021
@mcsf
Copy link
Contributor

mcsf commented Apr 8, 2021

I'm glad we're looking at this, because I believe there are more issues of state hiding under the surface. In both screencasts below, the dev tools are focused on Autocomplete's hooks; the third one from the top is filterValue.

  • In the first scenario, I ignore the completion suggestions (admin, user) and keep typing. It's clear to me that filterValue should not keep growing that way. We have already seen how this affects performance, but more bugs are bound to creep up, since this is a state that is not useful and doesn't correspond to developer expectations:
Gravacao.do.ecra.2021-04-08.as.11.07.41.mov
  • In the second scenario, I press Esc to dismiss completions for the first occurrence of @. I expect that to reset the autocomplete state, but it doesn't. Notice how that leads to a bug when I insert a second @, expecting to see user completions:
Gravacao.do.ecra.2021-04-08.as.11.10.04.mov

Conclusions:

  • The Autocomplete framework should have a self-imposed limit for its state, i.e. it should not rely on (or demand of) external completers to decide when to give up on matching.
  • But that is just a failsafe mechanism. Ideally, Autocomplete would be stricter overall and reset its own state more aggressively.

@mcsf
Copy link
Contributor

mcsf commented Apr 8, 2021

  • In the second scenario, I press Esc to dismiss completions for the first occurrence of @. I expect that to reset the autocomplete state, but it doesn't. Notice how that leads to a bug when I insert a second @, expecting to see user completions:

I was on a 1- or 2-day old trunk when I tested this. I believe this issue has been fixed by #30540.

@ockham
Copy link
Contributor

ockham commented Apr 8, 2021

The changes in #29939 are somewhat incompatible with the UX for the user autocompleter, its triggers can happen anywhere and stay on the editor even after the completion is done. Once the autocomplete finds the trigger, it runs through its matching/querying algorithm, but then doesn't know when to stop. What happens in practice is that the text after the trigger starts being considered as part of the text to match and it goes up to infinity.

That's an interesting discovery. Should we make a default limit of characters to match? Or maybe better, can we count the number of characters that you typed vs the last match and stop the autocompletion at some point? E.g. the last match is one two three four f and someone types ive six – it's 7 characters longer than the last match so we can consider that there is no chance to have another match and we can close the completers.

TBH I'd rather stop autocompletion after the first mismatch: Up until that point, the user will see the completion suggestions box, but if they keep typing and type something for which there are no suggestions, it makes sense to end auto-completion, IMO. That would also resolve the first item that @mcsf brought up in his comment.

I'm assuming that the main point for stopping autocompletion later -- e.g. after n words, or m characters -- would be to allow for a user to make a typo, notice it, and fix it (by pressing backspace), and have the completion suggestions box available again. While I do want this sort of behavior, I don't think that we should implement it through a customizable/per-completer/quantitative parameter (as that doesn't capture the essence of the problem IMO, and will lead to fairly arbitrary values of that parameter for individual completers, I think). Instead, maybe we can re-start the autocompleter once a user presses backspace.

We could maybe implement this in two steps (so it doesn't grow too complex):

  • Stop autocompletion upon mismatch.
  • Retrigger autocompletion upon pressing backspace.

@gziolo
Copy link
Member

gziolo commented Apr 9, 2021

We could maybe implement this in two steps (so it doesn't grow too complex):

  • Stop autocompletion upon mismatch.
  • Retrigger autocompletion upon pressing backspace.

@ockham, sounds like a good path to explore. The only question is how much work it is going to be to retrigger autocompletion when pressing the backspace.

@fullofcaffeine
Copy link
Member Author

fullofcaffeine commented Apr 9, 2021

Retrigger autocompletion upon pressing backspace.

I've found a simpler way to avoid triggering the match/completion upon a mismatch, but still unsure how to handle the retriggering of the autocomplete.

I have two WIP experiments:

  • This one basically bails out from the effect if we couldn't get any filtered options from the text. The problem here is how to retrigger the completion after they reach that condition since we need to call the setFilterValue and it's guarded by this condition. I've found checking if the last char is the trigger kinda works, allowing the effect to run if you type or reach the trigger char, but is not ideal, of course. The problem is that once it enters the mismatched state, it will only get back to autocompleting once we "reach" the trigger char again.

  • This follow-up experiment that tries the idea of restarting autocompletion upon backspace is pressed. The mismatch state is reached and we avoid the slowdown, but the problem here is that if we press the backspace after a lot of text, this text will be sent over to try to be matched, and we'll risk having the slowdown again (which would now be restricted to backspace presses in this case, though). We then go back to the original issue: I can't think of a way now to only match a portion of text with the user autocompleter. If we could limit the matched text, then we wouldn't have this problem in the first place. We only have the trigger char and we can't limit by spaces as the autocomplete is supposed to accept spaces, so how to know when to stop?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
[Package] Components /packages/components [Package] Editor /packages/editor [Type] Bug An existing feature does not function as intended
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants