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

feat: Update triggerCharacters plugin to support min characters #30

Merged
merged 5 commits into from
Sep 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@chatwoot/prosemirror-schema",
"version": "1.0.11",
"version": "1.0.13",
"description": "Schema setup for using prosemirror in chatwoot. Based on 👉 https://github.com/ProseMirror/prosemirror-example-setup/",
"main": "dist/index.js",
"scripts": {
Expand Down
32 changes: 22 additions & 10 deletions src/mentions/plugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,29 +6,41 @@
import { Plugin, PluginKey } from 'prosemirror-state';
import { Decoration, DecorationSet } from 'prosemirror-view';

export const triggerCharacters = char => $position => {
const regexp = new RegExp(`(?:^)?${char}[^\\s${char}]*`, 'g');
/**
* Creates a function to detect if the trigger character followed by a specified number of characters
* has been typed, starting from a new word or after a space.
* @param {string} char - The trigger character to detect.
* @param {number} [minChars=0] - The minimum number of characters that should follow the trigger character.
* @returns {Function} A function that takes a position object and returns true if the condition is met.
*/
export const triggerCharacters = (char, minChars = 0) => $position => {
iamsivin marked this conversation as resolved.
Show resolved Hide resolved
// Regular expression to find occurrences of 'char' followed by at least 'minChars' non-space characters.
// It matches these sequences starting from the beginning of the text or after a space.
const regexp = new RegExp(`(^|\\s)(${char}[^\\s${char}]{${minChars},})`, 'g');

// Get the position before the current cursor position in the document.
const textFrom = $position.before();
// Get the position at the end of the current node.
const textTo = $position.end();

// Get the text between the start of the node and the cursor position.
const text = $position.doc.textBetween(textFrom, textTo, '\0', '\0');

let match;

// eslint-disable-next-line
while ((match = regexp.exec(text))) {
const prefix = match.input.slice(Math.max(0, match.index - 1), match.index);
if (!/^[\s\0]?$/.test(prefix)) {
// eslint-disable-next-line
continue;
}
const beforeChar = match[1]; // Will be empty at start of text, or a space in the middle
const fullMatch = match[2]; // Includes the trigger character and following text

const from = match.index + $position.start();
let to = from + match[0].length;
const from = match.index + $position.start() + beforeChar.length;
const to = from + fullMatch.length;

if (from < $position.pos && to >= $position.pos) {
return { range: { from, to }, text: match[0] };
const trimmedText = fullMatch
? fullMatch.slice(char.length).trim()
: ""; // Remove trigger char and trim
return { range: { from, to }, text: trimmedText };
}
}
return null;
Expand Down
Loading