I wrote customm autocomplete logic in my code. But this autocomplete only performs word-based autocomplete. Spaces stop autocomplete.
function completions(context: any) {
const word = context.matchBefore(/\w*/);
// Return null if the current context is not explicitly triggered and doesn't match a word
if (word && word.from === word.to && !context.explicit) {
return null;
}
// Provide completion options based on the fetched data
return {
from: word!.from,
options: [...functions, ...variables].map((option: any) => {
return {
label: option.label,
type: option.type,
apply:
option.type === 'calculations' || option.type === 'inputs'
? `{{${option.id},y,x}}` // if the option is a formula (calculations or input), add the braces
: `${option.insert}`, // if the option is a function, single braces and add the insert text
detail: option.type,
description: option.description,
};
}),
};
}
This is custom completions function. I know that the problem is caused by regex, but even if I updated the regex, it causes other problems.
There isn’t enough info given to answer your question, e.g.
I personally use the parseTree to get the nodeBefore to determine when/what to autocomplete
import { syntaxTree } from '@codemirror/language'
const nodeBefore = syntaxTree(context.state).resolveInner(context.pos, -1)
1 Like
Thanks for answer.
/* eslint-disable import/no-extraneous-dependencies */
import { autocompletion } from '@codemirror/autocomplete';
import functions from './Functions';
/**
* Sets up autocompletion behavior in the editor based on a selected idiom.
* Fetches options from a JSON file corresponding to the idiom and configures autocompletion.
* @param {EditorView} editor - The CodeMirror EditorView instance.
* @param {Compartment} autocompleteCompartment - The compartment responsible for autocompletion.
* @param {NonNullable<Toptions['idiom']>} newIdiom - The new idiom to be used for autocompletion.
* @returns {Promise<any>} - A promise resolving upon successful autocompletion configuration.
* @throws {Error} - Throws an error if fetching the options fails.
*/
export async function setAutocompletionIdiom(
editor: any,
autocompleteCompartment: any,
variables: any,
) {
// Function to render additional content for the autocompletion options
function renderAdditionalContent(_completion: any, _state: any, _view: any) {
// Create a DOM node based on the completion
const additionalNode = document.createElement('div');
additionalNode.classList.add('cm-description');
additionalNode.textContent = `${_completion.description}`;
return additionalNode;
}
// Autocompletion configuration with additional options
const additionalOptions = [
{
position: 100,
render: (completion: any, state: any, view: any) =>
renderAdditionalContent(completion, state, view),
},
];
// Define completions for autocompletion based on the fetched options
function completions(context: any) {
const word = context.matchBefore(/\w*/);
// Return null if the current context is not explicitly triggered and doesn't match a word
if (word && word.from === word.to && !context.explicit) {
return null;
}
// Provide completion options based on the fetched data
return {
from: word!.from,
options: [...functions, ...variables].map((option: any) => {
return {
label: option.label,
type: option.type,
apply:
option.type === 'calculations' || option.type === 'inputs'
? `{{${option.id},y,x}}` // if the option is a formula (calculations or input), add the braces
: `${option.insert}`, // if the option is a function, single braces and add the insert text
detail: option.type,
description: option.description,
};
}),
};
}
/**
* Dispatches autocompletion configuration to the editor, updating the autocompletion behavior.
*
* @param {EditorView} editor - The EditorView instance where autocompletion is configured
* @param {Compartment} autocompleteCompartment - The Compartment managing autocompletion configurations
* @param {any[]} additionalOptions - Additional options to include in the autocompletion
* @param {any[]} completions - List of completions to override the default autocomplete options
* @returns {void}
*/
editor.dispatch({
effects: autocompleteCompartment.reconfigure(
autocompletion({
/**
* The maximum number of options to render in the autocomplete dropdown.
* @type {number}
*/
maxRenderedOptions: 10,
/**
* Determines whether the autocomplete dropdown should close on blur or not.
* @type {boolean}
*/
closeOnBlur: false,
/**
* Additional options to append to the default autocompletion options.
* @type {any[]}
*/
addToOptions: additionalOptions,
/**
* List of completions to override the default autocomplete options.
* @type {any[]}
*/
override: [completions],
/**
* Function providing a tooltip class for autocomplete options.
* @returns {string} - The class name for the tooltip
*/
tooltipClass: () => 'myTooltip',
/**
* Function providing an option class based on the option type.
* @param {any} option - The autocomplete option
* @returns {string} - The class name for the autocomplete option
*/
optionClass: (option: any) =>
option.type === 'secondary'
? 'cm-secondaryCompletion'
: 'cm-custom-main',
}),
),
});
}
This is full of the code for autocomplate feature.
- what other problems?
When i use diffrent experession for this const word = context.matchBefore(/\w*/);
, it autocomplete one time or it doesn’t work.
@AlexErrant How can i determine i am trying to check multiple words for the search? and not break on new spacE?
In this commit of my project I made spaces work for historical completions in my app’s search bar. Obviously YMMV, but a simple () => true
was enough for me. (Mostly because historical completions only make sense when from === 0
, i.e. when there are no other letters in the search bar.)
You can play with that search here. And here’s a screenshot of a search with a space working with completions.