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

Hash character with the suggestion utility conflicts with heading Markdown shortcut #2570

Open
2 tasks done
rfgamaral opened this issue Feb 23, 2022 · 18 comments · May be fixed by #4954
Open
2 tasks done

Hash character with the suggestion utility conflicts with heading Markdown shortcut #2570

rfgamaral opened this issue Feb 23, 2022 · 18 comments · May be fixed by #4954
Assignees
Labels
Type: Bug The issue or pullrequest is related to a bug

Comments

@rfgamaral
Copy link
Contributor

rfgamaral commented Feb 23, 2022

What’s the bug you are facing?

When using the # as the char in the Suggestion utility, this conflicts with the heading Markdown shortcut IF it's the first character in an empty paragraph. Instead of adding the selected suggestion, the paragraph is converted to a heading instead.

How can we reproduce the bug on our side?

  • Take the CodeSandbox as an example
  • Type # into the editor as the first character in an empty paragraph
  • Press Enter to select an item from the dropdown
  • Observe that the empty paragraph is converted into a heading

Can you provide a CodeSandbox?

What did you expect to happen?

The selected suggestion from the dropdown should've been added to the editor.

Anything to add? (optional)

A few observations:

  • I understand that I can disable the heading input rule to work around this issue, but we're looking for a way to have both things working.
  • After some research I've noticed that all input rules take priority over anything else (i.e. the input rules handleKeyDown will take precedence over other extensions/plugins handleKeyDown event handlers, that's why we have the behavior here described.
  • Possible solution: We need a way to sort ProseMirror plugins based on a priority property (similar to what we have for extensions) so that we can have certain plugins being handled before the input rules plugin.

Did you update your dependencies?

  • Yes, I’ve updated my dependencies to use the latest version of all packages.

Are you sponsoring us?

  • Yes, I’m a sponsor. 💖 (on behalf of Doist)
@rfgamaral rfgamaral added the Type: Bug The issue or pullrequest is related to a bug label Feb 23, 2022
@rfgamaral
Copy link
Contributor Author

FYI, as an ugly workaround, I'm handling the onCreate event, and doing this for the time being:

const { state, view } = props.editor

if (state.plugins.length > 0) {
    const restOfPlugins: Plugin[] = []
    const suggestionPlugins: Plugin[] = []

    state.plugins.forEach((plugin) => {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore: The `Plugin` type does not include `key`
        if ((plugin.key as string).includes('Suggestion')) {
            suggestionPlugins.push(plugin)
        } else {
            restOfPlugins.push(plugin)
        }
    })

    view.updateState(
        state.reconfigure({
            plugins: [...suggestionPlugins, ...restOfPlugins],
        }),
    )
}

Would love it if something akin to the extension priorities was possible for these ProseMirror plugins, so we can pick the ones we need to have a higher priority than the built-in ones, like the input rules.

@Cuimc
Copy link

Cuimc commented May 19, 2022

FYI, as an ugly workaround, I'm handling the onCreate event, and doing this for the time being:

const { state, view } = props.editor

if (state.plugins.length > 0) {
    const restOfPlugins: Plugin[] = []
    const suggestionPlugins: Plugin[] = []

    state.plugins.forEach((plugin) => {
        // eslint-disable-next-line @typescript-eslint/ban-ts-comment
        // @ts-ignore: The `Plugin` type does not include `key`
        if ((plugin.key as string).includes('Suggestion')) {
            suggestionPlugins.push(plugin)
        } else {
            restOfPlugins.push(plugin)
        }
    })

    view.updateState(
        state.reconfigure({
            plugins: [...suggestionPlugins, ...restOfPlugins],
        }),
    )
}

Would love it if something akin to the extension priorities was possible for these ProseMirror plugins, so we can pick the ones we need to have a higher priority than the built-in ones, like the input rules.

I also encountered this problem, But I don't see how to use this solution.
Maybe I'm a rookie
So could you explain it in detail? Thank you very much!!!

@rfgamaral
Copy link
Contributor Author

@cmcQDGCS You have to put that code in the onCreate event handler that you can attach to useEditor hook (assuming you're using React).

@Cuimc
Copy link

Cuimc commented May 20, 2022

@rfgamaral Thank you for your reply, No wonder I can't understand it. I use Vue. I'll study it again

@rfgamaral
Copy link
Contributor Author

It shouldn't matter what you use... In the same place you pass the extensions to use, handle the onCreate event there.

@Cuimc
Copy link

Cuimc commented May 20, 2022

@rfgamaral owowow!!I know what you mean!
but....When I went to loop editor plugins,No ”suggestion“
image

@rfgamaral
Copy link
Contributor Author

@cmcQDGCS We have multiple mention-like extensions, and we named them all with "suggestion" in the name (we don't use the official mention extension). You have to adapt that part to your needs. It seems you're using the official one, so changing (plugin.key as string).includes('Suggestion') to (plugin.key as string).includes('mention'), should work for you.

@Cuimc
Copy link

Cuimc commented May 20, 2022

@rfgamaral I tried, but I still haven't solved it...I don't know why.
But thank you very very very much for your answer
Maybe I'm too stupid. My understanding of tiptap is very shallow

@rfgamaral
Copy link
Contributor Author

Start explaining exactly what you're doing, and the problem you're having? Try to create a CodeSandbox minimal example, and explain the issue you're having.

@Cuimc
Copy link

Cuimc commented May 20, 2022

@rfgamaral
Copy link
Contributor Author

Tried to take a look, but I can't figure out what's wrong... Maybe you were right, and Vue works different on how it initializes the editor, which is having an impact on this. Maybe @bdbch can provide more insight here. Sorry, I'm a React developer, I barely know anything about Vue.

@Cuimc
Copy link

Cuimc commented May 20, 2022

Thank you very much for your help. I'll go and have a deep understanding

@KevinTss
Copy link

@rfgamaral does the priority have any effect on that issue?

@rfgamaral
Copy link
Contributor Author

@rfgamaral does the priority have any effect on that issue?

I don't think it does because the problem here lies in the ProseMirror plugins priority, and not the Tiptap extensions priority (which are 2 different things). As I've suggested in the OP, I think we need a way to override the priority for ProseMirror plugins, akin to the Extensions priority field.

@bdbch
Copy link
Contributor

bdbch commented Jun 24, 2022

@rfgamaral pointed it out well here. Right now you'd have to fallback to a dirty solution. I think a way to override the priorities of loaded ProseMirror plugins would be a neat way to solve this issue.

@Cuimc I'll take a look at your sandbox but have to say I'm also not a primary Vue developer.

@github-actions
Copy link

This issue is stale because it has been open 45 days with no activity. Remove stale label or comment or this will be closed in 7 days

@github-actions github-actions bot added the Info: Stale The issue or pullrequest has not been updated in a while and might be stale label Aug 10, 2022
@rfgamaral rfgamaral mentioned this issue Sep 15, 2022
10 tasks
@bdbch bdbch reopened this Sep 15, 2022
@bdbch bdbch added this to the 2.0.0 milestone Sep 15, 2022
@github-actions github-actions bot removed the Info: Stale The issue or pullrequest has not been updated in a while and might be stale label Sep 16, 2022
@bdbch bdbch removed this from the 2.0.0 milestone Feb 23, 2023
@Nantris
Copy link
Contributor

Nantris commented May 9, 2023

This is really painful. Is there any easier workaround for this?

@bdbch bdbch self-assigned this Aug 4, 2023
@jaggy
Copy link

jaggy commented Jan 17, 2024

Hi there, just ran into this now. Here's how I fixed this on my end. I'm using Vue tiptap but I think this should work for everyone. Here's some context so you know if this applies to you as well.

  • I don't want enter to apply to heading markdown, only spaces.

What I did is extend the heading extension, modify the input rule to only support spaces after the #.

Heading.extend({
    addInputRules() {
        return this.options.levels.map((level) => {
            return textblockTypeInputRule({
-                find: new RegExp(`^(#{1,${level}})\\s$`),
+                find: new RegExp(`^(#{1,${level}}) $`),
                type: this.type,
                getAttributes: {
                    level,
                },
            })
        })
    },
})

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug The issue or pullrequest is related to a bug
Projects
Status: Backlog
Development

Successfully merging a pull request may close this issue.

6 participants