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

FIX: code "block" detection before showing autocomplete #26023

Merged
merged 1 commit into from Mar 11, 2024

Conversation

ZogStriP
Copy link
Member

@ZogStriP ZogStriP commented Mar 4, 2024

TL;DR: Refactor autocomplete to use async markdown parsing for code block detection.

Previously, the inCodeBlock function in discourse/app/lib/utilities.js used regular expressions to determine if a given position in the text was inside a code block. This approach had some limitations and could lead to incorrect behavior in certain edge cases.

This commit refactors inCodeBlock to use a more robust algorithm that leverages Discourse's markdown parsing library.

The new approach works as follows:

  1. Check if the text contains any code block markers using a regular expression.
    If not, return false since the cursor can't be in a code block.
  2. If potential code blocks exist, find a unique marker character that doesn't appear in the text.
  3. Insert the unique marker character into the text at the cursor position.
  4. Parse the modified text using Discourse's markdown parser, which converts the markdown into a tree of tokens.
  5. Traverse the token tree to find the token that contains the unique marker character.
  6. Check if the token's type is one of the types representing code blocks ("code_inline", "code_block", or "fence").
    If so, return true, indicating that the cursor is inside a code block.
    Otherwise, return false.

This algorithm provides a more accurate way to determine the cursor's position in relation to code blocks, accounting for the various ways code blocks can be represented in markdown.

To accommodate this change, the autocomplete triggerRule option is now an async function.

The autocomplete logic in composer-editor.js, d-editor.js, and hashtag-autocomplete.js has been updated to handle the async nature of inCodeBlock.

Additionally, many of the tests have been refactored to handle async behavior. The test helpers now simulate typing and autocomplete selection in a more realistic, step-by-step manner. This should make the tests more robust and reflective of real-world usage.

This is a significant refactor that touches multiple parts of the codebase, but it should lead to more accurate and reliable autocomplete behavior, especially when dealing with code blocks in the editor.

Written by an πŸ€– LLM. Edited by a πŸ§‘β€πŸ’» human.

@ZogStriP
Copy link
Member Author

ZogStriP commented Mar 4, 2024

  • I probably broke some autocomplete tests with my changes, but I can't seem to be able to run the qunit tests locally - all my browsers (Safari, Chrome, and Firefox) crash after ~2000 tests πŸ’₯.

Welp, I did πŸ˜… Will have a look tomorrow.

@ZogStriP ZogStriP force-pushed the fix-in-code-block-detection branch from 162f0d3 to 621a9b0 Compare March 8, 2024 16:03
@github-actions github-actions bot added the chat PRs which include a change to Chat plugin label Mar 8, 2024
@ZogStriP ZogStriP force-pushed the fix-in-code-block-detection branch from 59a544a to 8a48270 Compare March 9, 2024 18:08
@ZogStriP ZogStriP force-pushed the fix-in-code-block-detection branch from 8a48270 to fa48e09 Compare March 9, 2024 18:17
@ZogStriP ZogStriP added the javascript Pull requests that update Javascript code label Mar 9, 2024
@CvX CvX self-requested a review March 10, 2024 19:56
**TL;DR:** Refactor autocomplete to use async markdown parsing for code block detection.

Previously, the `inCodeBlock` function in `discourse/app/lib/utilities.js` used regular expressions to determine if a given position in the text was inside a code block. This approach had some limitations and could lead to incorrect behavior in certain edge cases.

This commit refactors `inCodeBlock` to use a more robust algorithm that leverages Discourse's markdown parsing library.

The new approach works as follows:

1. Check if the text contains any code block markers using a regular expression.
   If not, return `false` since the cursor can't be in a code block.
1. If potential code blocks exist, find a unique marker character that doesn't appear in the text.
1. Insert the unique marker character into the text at the cursor position.
1. Parse the modified text using Discourse's markdown parser, which converts the markdown into a tree of tokens.
1. Traverse the token tree to find the token that contains the unique marker character.
1. Check if the token's type is one of the types representing code blocks ("code_inline", "code_block", or "fence").
   If so, return `true`, indicating that the cursor is inside a code block.
   Otherwise, return `false`.

This algorithm provides a more accurate way to determine the cursor's position in relation to code blocks, accounting for the various ways code blocks can be represented in markdown.

To accommodate this change, the autocomplete `triggerRule` option is now an async function.

The autocomplete logic in `composer-editor.js`, `d-editor.js`, and `hashtag-autocomplete.js` has been updated to handle the async nature of `inCodeBlock`.

Additionally, many of the tests have been refactored to handle async behavior. The test helpers now simulate typing and autocomplete selection in a more realistic, step-by-step manner. This should make the tests more robust and reflective of real-world usage.

This is a significant refactor that touches multiple parts of the codebase, but it should lead to more accurate and reliable autocomplete behavior, especially when dealing with code blocks in the editor.

> Written by an πŸ€– LLM. Edited by a πŸ§‘β€πŸ’» human.
@ZogStriP ZogStriP force-pushed the fix-in-code-block-detection branch from fa48e09 to 472f719 Compare March 11, 2024 16:22
@ZogStriP ZogStriP merged commit 47d1703 into main Mar 11, 2024
16 checks passed
@ZogStriP ZogStriP deleted the fix-in-code-block-detection branch March 11, 2024 16:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
chat PRs which include a change to Chat plugin javascript Pull requests that update Javascript code
2 participants