Skip to content

Commit

Permalink
feat: allow to specify parser dialect
Browse files Browse the repository at this point in the history
This enables parser dialects (i.e. `camunda`), as supported by the
underlying language tooling, hence accepting backtick escaped variable
names such as `foo + bar`.

Related to camunda/camunda-modeler#3983
Related to camunda/camunda-modeler#3338
  • Loading branch information
nikku committed Jan 23, 2025
1 parent 5aca9cb commit ca6705e
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 16 deletions.
13 changes: 10 additions & 3 deletions src/core/facets.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
import { Facet } from '@codemirror/state';

/**
* @typedef { 'expression' | 'unaryTests' } Dialect
* @typedef { import('../language').Dialect } Dialect
* @typedef { import('../language').ParserDialect } ParserDialect
* @typedef { import('..').Variable } Variable
*/

Expand All @@ -16,6 +17,12 @@ export const builtinsFacet = Facet.define();
export const variablesFacet = Facet.define();

/**
* @type {Facet<dialect>}
* @type {Facet<Dialect>}
*/
export const dialectFacet = Facet.define();
export const dialectFacet = Facet.define();

/**
* @type {Facet<ParserDialect>}
*/
export const parserDialectFacet = Facet.define();

9 changes: 8 additions & 1 deletion src/core/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { createContext, language } from '../language';
import {
variablesFacet,
builtinsFacet,
parserDialectFacet,
dialectFacet
} from './facets';

Expand All @@ -23,6 +24,7 @@ import {
/**
* @typedef { {
* dialect?: import('../language').Dialect,
* parserDialect?: import('../language').ParserDialect,
* variables?: Variable[],
* builtins?: Variable[]
* } } CoreConfig
Expand All @@ -38,6 +40,7 @@ import {
*/
export function configure({
dialect = 'expression',
parserDialect,
variables = [],
builtins = [],
completions = feelCompletions({ builtins, variables })
Expand All @@ -49,8 +52,10 @@ export function configure({
dialectFacet.of(dialect),
builtinsFacet.of(builtins),
variablesFacet.of(variables),
parserDialectFacet.of(parserDialect),
language({
dialect,
parserDialect,
context,
completions
})
Expand All @@ -67,10 +72,12 @@ export function get(state) {
const builtins = state.facet(builtinsFacet)[0];
const variables = state.facet(variablesFacet)[0];
const dialect = state.facet(dialectFacet)[0];
const parserDialect = state.facet(parserDialectFacet)[0];

return {
builtins,
variables,
dialect
dialect,
parserDialect
};
}
20 changes: 11 additions & 9 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ import { camunda as camundaBuiltins } from './builtins';
* @typedef { import('./core').Variable } Variable
*/

/**
* @typedef { import('./language').Dialect } Dialect
* @typedef { import('./language').ParserDialect } ParserDialect
*/

/**
* @typedef {object} Builtin
* @property {string} name
Expand All @@ -33,6 +38,7 @@ const placeholderConf = new Compartment();
* @param {DOMNode} config.container
* @param {Extension[]} [config.extensions]
* @param {Dialect} [config.dialect='expression']
* @param {ParserDialect} [config.parserDialect]
* @param {DOMNode|String} [config.tooltipContainer]
* @param {Function} [config.onChange]
* @param {Function} [config.onKeyDown]
Expand All @@ -41,12 +47,11 @@ const placeholderConf = new Compartment();
* @param {String} [config.value]
* @param {Variable[]} [config.variables]
* @param {Variable[]} [config.builtins]
*
* @returns {Object} editor
*/
export default function FeelEditor({
extensions: editorExtensions = [],
dialect = 'expression',
parserDialect,
container,
contentAttributes = {},
tooltipContainer,
Expand Down Expand Up @@ -101,7 +106,8 @@ export default function FeelEditor({
coreConf.of(Core.configure({
dialect,
builtins,
variables
variables,
parserDialect
})),
bracketMatching(),
indentOnInput(),
Expand Down Expand Up @@ -185,16 +191,12 @@ FeelEditor.prototype.getSelection = function() {
*/
FeelEditor.prototype.setVariables = function(variables) {

const {
dialect,
builtins
} = Core.get(this._cmEditor.state);
const config = Core.get(this._cmEditor.state);

this._cmEditor.dispatch({
effects: [
coreConf.reconfigure(Core.configure({
dialect,
builtins,
...config,
variables
}))
]
Expand Down
5 changes: 5 additions & 0 deletions src/language/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@ import { feel } from 'lang-feel';
* @typedef { 'expression' | 'unaryTests' } Dialect
*/

/**
* @typedef { 'camunda' | undefined } ParserDialect
*/

/**
* @param { {
* dialect?: Dialect,
* parserDialect?: ParserDialect,
* context?: Record<string, any>,
* completions?: import('@codemirror/autocomplete').CompletionSource[]
* } } options
Expand Down
8 changes: 5 additions & 3 deletions test/spec/CodeEditor.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -481,16 +481,18 @@ return

[
{ dialect: 'expression', value: 'Mike < 10' },
{ dialect: 'unaryTests', value: '12, now(), "STRING"' }
].forEach(({ dialect, value }) => {
{ dialect: 'unaryTests', value: '12, now(), "STRING"' },
{ dialect: 'expression', value: '`a + 1`', parserDialect: 'camunda' }
].forEach(({ dialect, parserDialect, value }) => {

it(`<${dialect}>`, async function() {

// given
const editor = new FeelEditor({
container,
value,
dialect
dialect,
parserDialect
});

// when
Expand Down

0 comments on commit ca6705e

Please sign in to comment.