Merge branch 'master' into feat/url-binding-default
This commit is contained in:
commit
9a17664ac4
|
@ -53,7 +53,7 @@
|
||||||
"@budibase/shared-core": "*",
|
"@budibase/shared-core": "*",
|
||||||
"@budibase/string-templates": "*",
|
"@budibase/string-templates": "*",
|
||||||
"@budibase/types": "*",
|
"@budibase/types": "*",
|
||||||
"@codemirror/autocomplete": "^6.7.1",
|
"@codemirror/autocomplete": "6.9.0",
|
||||||
"@codemirror/commands": "^6.2.4",
|
"@codemirror/commands": "^6.2.4",
|
||||||
"@codemirror/lang-javascript": "^6.1.8",
|
"@codemirror/lang-javascript": "^6.1.8",
|
||||||
"@codemirror/language": "^6.6.0",
|
"@codemirror/language": "^6.6.0",
|
||||||
|
|
|
@ -45,10 +45,11 @@
|
||||||
import { EditorModes } from "./"
|
import { EditorModes } from "./"
|
||||||
import { themeStore } from "@/stores/portal"
|
import { themeStore } from "@/stores/portal"
|
||||||
import type { EditorMode } from "@budibase/types"
|
import type { EditorMode } from "@budibase/types"
|
||||||
|
import type { BindingCompletion } from "@/types"
|
||||||
|
|
||||||
export let label: string | undefined = undefined
|
export let label: string | undefined = undefined
|
||||||
// TODO: work out what best type fits this
|
// TODO: work out what best type fits this
|
||||||
export let completions: any[] = []
|
export let completions: BindingCompletion[] = []
|
||||||
export let mode: EditorMode = EditorModes.Handlebars
|
export let mode: EditorMode = EditorModes.Handlebars
|
||||||
export let value: string | null = ""
|
export let value: string | null = ""
|
||||||
export let placeholder: string | null = null
|
export let placeholder: string | null = null
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
import { getManifest } from "@budibase/string-templates"
|
import { getManifest } from "@budibase/string-templates"
|
||||||
import sanitizeHtml from "sanitize-html"
|
import sanitizeHtml from "sanitize-html"
|
||||||
import { groupBy } from "lodash"
|
import { groupBy } from "lodash"
|
||||||
import {
|
import { EditorModesMap, Helper, Snippet } from "@budibase/types"
|
||||||
BindingCompletion,
|
|
||||||
EditorModesMap,
|
|
||||||
Helper,
|
|
||||||
Snippet,
|
|
||||||
} from "@budibase/types"
|
|
||||||
import { CompletionContext } from "@codemirror/autocomplete"
|
import { CompletionContext } from "@codemirror/autocomplete"
|
||||||
|
import { EditorView } from "@codemirror/view"
|
||||||
|
import { BindingCompletion, BindingCompletionOption } from "@/types"
|
||||||
|
|
||||||
export const EditorModes: EditorModesMap = {
|
export const EditorModes: EditorModesMap = {
|
||||||
JS: {
|
JS: {
|
||||||
|
@ -25,15 +22,7 @@ export const EditorModes: EditorModesMap = {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
export const SECTIONS = {
|
const buildHelperInfoNode = (helper: Helper) => {
|
||||||
HB_HELPER: {
|
|
||||||
name: "Helper",
|
|
||||||
type: "helper",
|
|
||||||
icon: "Code",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
export const buildHelperInfoNode = (completion: any, helper: Helper) => {
|
|
||||||
const ele = document.createElement("div")
|
const ele = document.createElement("div")
|
||||||
ele.classList.add("info-bubble")
|
ele.classList.add("info-bubble")
|
||||||
|
|
||||||
|
@ -65,7 +54,7 @@ const toSpectrumIcon = (name: string) => {
|
||||||
</svg>`
|
</svg>`
|
||||||
}
|
}
|
||||||
|
|
||||||
export const buildSectionHeader = (
|
const buildSectionHeader = (
|
||||||
type: string,
|
type: string,
|
||||||
sectionName: string,
|
sectionName: string,
|
||||||
icon: string,
|
icon: string,
|
||||||
|
@ -84,30 +73,27 @@ export const buildSectionHeader = (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const helpersToCompletion = (
|
const helpersToCompletion = (
|
||||||
helpers: Record<string, Helper>,
|
helpers: Record<string, Helper>,
|
||||||
mode: { name: "javascript" | "handlebars" }
|
mode: { name: "javascript" | "handlebars" }
|
||||||
) => {
|
): BindingCompletionOption[] => {
|
||||||
const { type, name: sectionName, icon } = SECTIONS.HB_HELPER
|
const helperSection = buildSectionHeader("helper", "Helpers", "Code", 99)
|
||||||
const helperSection = buildSectionHeader(type, sectionName, icon, 99)
|
|
||||||
|
|
||||||
return Object.keys(helpers).flatMap(helperName => {
|
return Object.keys(helpers).flatMap(helperName => {
|
||||||
let helper = helpers[helperName]
|
const helper = helpers[helperName]
|
||||||
return {
|
return {
|
||||||
label: helperName,
|
label: helperName,
|
||||||
info: (completion: BindingCompletion) => {
|
info: () => buildHelperInfoNode(helper),
|
||||||
return buildHelperInfoNode(completion, helper)
|
|
||||||
},
|
|
||||||
type: "helper",
|
type: "helper",
|
||||||
section: helperSection,
|
section: helperSection,
|
||||||
detail: "Function",
|
detail: "Function",
|
||||||
apply: (
|
apply: (
|
||||||
view: any,
|
view: EditorView,
|
||||||
completion: BindingCompletion,
|
_completion: BindingCompletionOption,
|
||||||
from: number,
|
from: number,
|
||||||
to: number
|
to: number
|
||||||
) => {
|
) => {
|
||||||
insertBinding(view, from, to, helperName, mode)
|
insertBinding(view, from, to, helperName, mode, AutocompleteType.HELPER)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -115,7 +101,7 @@ export const helpersToCompletion = (
|
||||||
|
|
||||||
export const getHelperCompletions = (mode: {
|
export const getHelperCompletions = (mode: {
|
||||||
name: "javascript" | "handlebars"
|
name: "javascript" | "handlebars"
|
||||||
}) => {
|
}): BindingCompletionOption[] => {
|
||||||
// TODO: manifest needs to be properly typed
|
// TODO: manifest needs to be properly typed
|
||||||
const manifest: any = getManifest()
|
const manifest: any = getManifest()
|
||||||
return Object.keys(manifest).flatMap(key => {
|
return Object.keys(manifest).flatMap(key => {
|
||||||
|
@ -123,49 +109,33 @@ export const getHelperCompletions = (mode: {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const snippetAutoComplete = (snippets: Snippet[]) => {
|
export const snippetAutoComplete = (snippets: Snippet[]): BindingCompletion => {
|
||||||
return function myCompletions(context: CompletionContext) {
|
return setAutocomplete(
|
||||||
if (!snippets?.length) {
|
snippets.map(snippet => ({
|
||||||
return null
|
section: buildSectionHeader("snippets", "Snippets", "Code", 100),
|
||||||
}
|
|
||||||
const word = context.matchBefore(/\w*/)
|
|
||||||
if (!word || (word.from == word.to && !context.explicit)) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
from: word.from,
|
|
||||||
options: snippets.map(snippet => ({
|
|
||||||
label: `snippets.${snippet.name}`,
|
label: `snippets.${snippet.name}`,
|
||||||
type: "text",
|
displayLabel: snippet.name,
|
||||||
simple: true,
|
}))
|
||||||
apply: (
|
)
|
||||||
view: any,
|
|
||||||
completion: BindingCompletion,
|
|
||||||
from: number,
|
|
||||||
to: number
|
|
||||||
) => {
|
|
||||||
insertSnippet(view, from, to, completion.label)
|
|
||||||
},
|
|
||||||
})),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const bindingFilter = (options: BindingCompletion[], query: string) => {
|
const bindingFilter = (options: BindingCompletionOption[], query: string) => {
|
||||||
return options.filter(completion => {
|
return options.filter(completion => {
|
||||||
const section_parsed = completion.section.name.toLowerCase()
|
const section_parsed = completion.section?.toString().toLowerCase()
|
||||||
const label_parsed = completion.label.toLowerCase()
|
const label_parsed = completion.label.toLowerCase()
|
||||||
const query_parsed = query.toLowerCase()
|
const query_parsed = query.toLowerCase()
|
||||||
|
|
||||||
return (
|
return (
|
||||||
section_parsed.includes(query_parsed) ||
|
section_parsed?.includes(query_parsed) ||
|
||||||
label_parsed.includes(query_parsed)
|
label_parsed.includes(query_parsed)
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const hbAutocomplete = (baseCompletions: BindingCompletion[]) => {
|
export const hbAutocomplete = (
|
||||||
async function coreCompletion(context: CompletionContext) {
|
baseCompletions: BindingCompletionOption[]
|
||||||
|
): BindingCompletion => {
|
||||||
|
function coreCompletion(context: CompletionContext) {
|
||||||
let bindingStart = context.matchBefore(EditorModes.Handlebars.match)
|
let bindingStart = context.matchBefore(EditorModes.Handlebars.match)
|
||||||
|
|
||||||
let options = baseCompletions || []
|
let options = baseCompletions || []
|
||||||
|
@ -191,9 +161,15 @@ export const hbAutocomplete = (baseCompletions: BindingCompletion[]) => {
|
||||||
return coreCompletion
|
return coreCompletion
|
||||||
}
|
}
|
||||||
|
|
||||||
export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => {
|
function wrappedAutocompleteMatch(context: CompletionContext) {
|
||||||
async function coreCompletion(context: CompletionContext) {
|
return context.matchBefore(/\$\("[\s\w]*/)
|
||||||
let jsBinding = context.matchBefore(/\$\("[\s\w]*/)
|
}
|
||||||
|
|
||||||
|
export const jsAutocomplete = (
|
||||||
|
baseCompletions: BindingCompletionOption[]
|
||||||
|
): BindingCompletion => {
|
||||||
|
function coreCompletion(context: CompletionContext) {
|
||||||
|
let jsBinding = wrappedAutocompleteMatch(context)
|
||||||
let options = baseCompletions || []
|
let options = baseCompletions || []
|
||||||
|
|
||||||
if (jsBinding) {
|
if (jsBinding) {
|
||||||
|
@ -217,10 +193,42 @@ export const jsAutocomplete = (baseCompletions: BindingCompletion[]) => {
|
||||||
return coreCompletion
|
return coreCompletion
|
||||||
}
|
}
|
||||||
|
|
||||||
export const buildBindingInfoNode = (
|
export const jsHelperAutocomplete = (
|
||||||
completion: BindingCompletion,
|
baseCompletions: BindingCompletionOption[]
|
||||||
binding: any
|
): BindingCompletion => {
|
||||||
) => {
|
return setAutocomplete(
|
||||||
|
baseCompletions.map(helper => ({
|
||||||
|
...helper,
|
||||||
|
displayLabel: helper.label,
|
||||||
|
label: `helpers.${helper.label}()`,
|
||||||
|
}))
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function setAutocomplete(
|
||||||
|
options: BindingCompletionOption[]
|
||||||
|
): BindingCompletion {
|
||||||
|
return function (context: CompletionContext) {
|
||||||
|
if (wrappedAutocompleteMatch(context)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
const word = context.matchBefore(/\b\w*(\.\w*)?/)
|
||||||
|
if (!word || (word.from == word.to && !context.explicit)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
from: word.from,
|
||||||
|
options,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildBindingInfoNode = (binding: {
|
||||||
|
valueHTML: string
|
||||||
|
value: string | null
|
||||||
|
}) => {
|
||||||
if (!binding.valueHTML || binding.value == null) {
|
if (!binding.valueHTML || binding.value == null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -278,18 +286,28 @@ export function jsInsert(
|
||||||
return parsedInsert
|
return parsedInsert
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const enum AutocompleteType {
|
||||||
|
BINDING,
|
||||||
|
HELPER,
|
||||||
|
TEXT,
|
||||||
|
}
|
||||||
|
|
||||||
// Autocomplete apply behaviour
|
// Autocomplete apply behaviour
|
||||||
export const insertBinding = (
|
const insertBinding = (
|
||||||
view: any,
|
view: EditorView,
|
||||||
from: number,
|
from: number,
|
||||||
to: number,
|
to: number,
|
||||||
text: string,
|
text: string,
|
||||||
mode: { name: "javascript" | "handlebars" }
|
mode: { name: "javascript" | "handlebars" },
|
||||||
|
type: AutocompleteType
|
||||||
) => {
|
) => {
|
||||||
let parsedInsert
|
let parsedInsert
|
||||||
|
|
||||||
if (mode.name == "javascript") {
|
if (mode.name == "javascript") {
|
||||||
parsedInsert = jsInsert(view.state.doc?.toString(), from, to, text)
|
parsedInsert = jsInsert(view.state.doc?.toString(), from, to, text, {
|
||||||
|
helper: type === AutocompleteType.HELPER,
|
||||||
|
disableWrapping: type === AutocompleteType.TEXT,
|
||||||
|
})
|
||||||
} else if (mode.name == "handlebars") {
|
} else if (mode.name == "handlebars") {
|
||||||
parsedInsert = hbInsert(view.state.doc?.toString(), from, to, text)
|
parsedInsert = hbInsert(view.state.doc?.toString(), from, to, text)
|
||||||
} else {
|
} else {
|
||||||
|
@ -319,30 +337,11 @@ export const insertBinding = (
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const insertSnippet = (
|
|
||||||
view: any,
|
|
||||||
from: number,
|
|
||||||
to: number,
|
|
||||||
text: string
|
|
||||||
) => {
|
|
||||||
let cursorPos = from + text.length
|
|
||||||
view.dispatch({
|
|
||||||
changes: {
|
|
||||||
from,
|
|
||||||
to,
|
|
||||||
insert: text,
|
|
||||||
},
|
|
||||||
selection: {
|
|
||||||
anchor: cursorPos,
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: typing in this function isn't great
|
// TODO: typing in this function isn't great
|
||||||
export const bindingsToCompletions = (
|
export const bindingsToCompletions = (
|
||||||
bindings: any,
|
bindings: any,
|
||||||
mode: { name: "javascript" | "handlebars" }
|
mode: { name: "javascript" | "handlebars" }
|
||||||
) => {
|
): BindingCompletionOption[] => {
|
||||||
const bindingByCategory = groupBy(bindings, "category")
|
const bindingByCategory = groupBy(bindings, "category")
|
||||||
const categoryMeta = bindings?.reduce((acc: any, ele: any) => {
|
const categoryMeta = bindings?.reduce((acc: any, ele: any) => {
|
||||||
acc[ele.category] = acc[ele.category] || {}
|
acc[ele.category] = acc[ele.category] || {}
|
||||||
|
@ -356,8 +355,9 @@ export const bindingsToCompletions = (
|
||||||
return acc
|
return acc
|
||||||
}, {})
|
}, {})
|
||||||
|
|
||||||
const completions = Object.keys(bindingByCategory).reduce(
|
const completions = Object.keys(bindingByCategory).reduce<
|
||||||
(comps: any, catKey: string) => {
|
BindingCompletionOption[]
|
||||||
|
>((comps, catKey) => {
|
||||||
const { icon, rank } = categoryMeta[catKey] || {}
|
const { icon, rank } = categoryMeta[catKey] || {}
|
||||||
|
|
||||||
const bindingSectionHeader = buildSectionHeader(
|
const bindingSectionHeader = buildSectionHeader(
|
||||||
|
@ -368,34 +368,41 @@ export const bindingsToCompletions = (
|
||||||
typeof rank == "number" ? rank : 1
|
typeof rank == "number" ? rank : 1
|
||||||
)
|
)
|
||||||
|
|
||||||
return [
|
comps.push(
|
||||||
...comps,
|
...bindingByCategory[catKey].reduce<BindingCompletionOption[]>(
|
||||||
...bindingByCategory[catKey].reduce((acc, binding) => {
|
(acc, binding) => {
|
||||||
let displayType = binding.fieldSchema?.type || binding.display?.type
|
let displayType = binding.fieldSchema?.type || binding.display?.type
|
||||||
acc.push({
|
acc.push({
|
||||||
label:
|
label:
|
||||||
binding.display?.name || binding.readableBinding || "NO NAME",
|
binding.display?.name || binding.readableBinding || "NO NAME",
|
||||||
info: (completion: BindingCompletion) => {
|
info: () => buildBindingInfoNode(binding),
|
||||||
return buildBindingInfoNode(completion, binding)
|
|
||||||
},
|
|
||||||
type: "binding",
|
type: "binding",
|
||||||
detail: displayType,
|
detail: displayType,
|
||||||
section: bindingSectionHeader,
|
section: bindingSectionHeader,
|
||||||
apply: (
|
apply: (
|
||||||
view: any,
|
view: EditorView,
|
||||||
completion: BindingCompletion,
|
_completion: BindingCompletionOption,
|
||||||
from: number,
|
from: number,
|
||||||
to: number
|
to: number
|
||||||
) => {
|
) => {
|
||||||
insertBinding(view, from, to, binding.readableBinding, mode)
|
insertBinding(
|
||||||
|
view,
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
binding.readableBinding,
|
||||||
|
mode,
|
||||||
|
AutocompleteType.BINDING
|
||||||
|
)
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
return acc
|
return acc
|
||||||
}, []),
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
[]
|
[]
|
||||||
)
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
return comps
|
||||||
|
}, [])
|
||||||
|
|
||||||
return completions
|
return completions
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@
|
||||||
snippetAutoComplete,
|
snippetAutoComplete,
|
||||||
EditorModes,
|
EditorModes,
|
||||||
bindingsToCompletions,
|
bindingsToCompletions,
|
||||||
|
jsHelperAutocomplete,
|
||||||
} from "../CodeEditor"
|
} from "../CodeEditor"
|
||||||
import BindingSidePanel from "./BindingSidePanel.svelte"
|
import BindingSidePanel from "./BindingSidePanel.svelte"
|
||||||
import EvaluationSidePanel from "./EvaluationSidePanel.svelte"
|
import EvaluationSidePanel from "./EvaluationSidePanel.svelte"
|
||||||
|
@ -34,7 +35,6 @@
|
||||||
import { BindingMode, SidePanel } from "@budibase/types"
|
import { BindingMode, SidePanel } from "@budibase/types"
|
||||||
import type {
|
import type {
|
||||||
EnrichedBinding,
|
EnrichedBinding,
|
||||||
BindingCompletion,
|
|
||||||
Snippet,
|
Snippet,
|
||||||
Helper,
|
Helper,
|
||||||
CaretPositionFn,
|
CaretPositionFn,
|
||||||
|
@ -42,7 +42,7 @@
|
||||||
JSONValue,
|
JSONValue,
|
||||||
} from "@budibase/types"
|
} from "@budibase/types"
|
||||||
import type { Log } from "@budibase/string-templates"
|
import type { Log } from "@budibase/string-templates"
|
||||||
import type { CompletionContext } from "@codemirror/autocomplete"
|
import type { BindingCompletion, BindingCompletionOption } from "@/types"
|
||||||
|
|
||||||
const dispatch = createEventDispatcher()
|
const dispatch = createEventDispatcher()
|
||||||
|
|
||||||
|
@ -91,7 +91,10 @@
|
||||||
$: bindingCompletions = bindingsToCompletions(enrichedBindings, editorMode)
|
$: bindingCompletions = bindingsToCompletions(enrichedBindings, editorMode)
|
||||||
$: bindingHelpers = new BindingHelpers(getCaretPosition, insertAtPos)
|
$: bindingHelpers = new BindingHelpers(getCaretPosition, insertAtPos)
|
||||||
$: hbsCompletions = getHBSCompletions(bindingCompletions)
|
$: hbsCompletions = getHBSCompletions(bindingCompletions)
|
||||||
$: jsCompletions = getJSCompletions(bindingCompletions, snippets, useSnippets)
|
$: jsCompletions = getJSCompletions(bindingCompletions, snippets, {
|
||||||
|
useHelpers: allowHelpers,
|
||||||
|
useSnippets,
|
||||||
|
})
|
||||||
$: {
|
$: {
|
||||||
// Ensure a valid side panel option is always selected
|
// Ensure a valid side panel option is always selected
|
||||||
if (sidePanel && !sidePanelOptions.includes(sidePanel)) {
|
if (sidePanel && !sidePanelOptions.includes(sidePanel)) {
|
||||||
|
@ -99,7 +102,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const getHBSCompletions = (bindingCompletions: BindingCompletion[]) => {
|
const getHBSCompletions = (bindingCompletions: BindingCompletionOption[]) => {
|
||||||
return [
|
return [
|
||||||
hbAutocomplete([
|
hbAutocomplete([
|
||||||
...bindingCompletions,
|
...bindingCompletions,
|
||||||
|
@ -109,17 +112,23 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
const getJSCompletions = (
|
const getJSCompletions = (
|
||||||
bindingCompletions: BindingCompletion[],
|
bindingCompletions: BindingCompletionOption[],
|
||||||
snippets: Snippet[] | null,
|
snippets: Snippet[] | null,
|
||||||
useSnippets?: boolean
|
config: {
|
||||||
|
useHelpers: boolean
|
||||||
|
useSnippets: boolean
|
||||||
|
}
|
||||||
) => {
|
) => {
|
||||||
const completions: ((_: CompletionContext) => any)[] = [
|
const completions: BindingCompletion[] = []
|
||||||
jsAutocomplete([
|
if (bindingCompletions.length) {
|
||||||
...bindingCompletions,
|
completions.push(jsAutocomplete([...bindingCompletions]))
|
||||||
...getHelperCompletions(EditorModes.JS),
|
}
|
||||||
]),
|
if (config.useHelpers) {
|
||||||
]
|
completions.push(
|
||||||
if (useSnippets && snippets) {
|
jsHelperAutocomplete([...getHelperCompletions(EditorModes.JS)])
|
||||||
|
)
|
||||||
|
}
|
||||||
|
if (config.useSnippets && snippets) {
|
||||||
completions.push(snippetAutoComplete(snippets))
|
completions.push(snippetAutoComplete(snippets))
|
||||||
}
|
}
|
||||||
return completions
|
return completions
|
||||||
|
@ -381,7 +390,7 @@
|
||||||
autofocus={autofocusEditor}
|
autofocus={autofocusEditor}
|
||||||
placeholder={placeholder ||
|
placeholder={placeholder ||
|
||||||
"Add bindings by typing $ or use the menu on the right"}
|
"Add bindings by typing $ or use the menu on the right"}
|
||||||
jsBindingWrapping
|
jsBindingWrapping={bindingCompletions.length > 0}
|
||||||
/>
|
/>
|
||||||
{/key}
|
{/key}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
|
@ -118,6 +118,7 @@
|
||||||
allowHBS={false}
|
allowHBS={false}
|
||||||
allowJS
|
allowJS
|
||||||
allowSnippets={false}
|
allowSnippets={false}
|
||||||
|
allowHelpers={false}
|
||||||
showTabBar={false}
|
showTabBar={false}
|
||||||
placeholder="return function(input) ❴ ... ❵"
|
placeholder="return function(input) ❴ ... ❵"
|
||||||
value={code}
|
value={code}
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
import { CompletionContext, Completion } from "@codemirror/autocomplete"
|
||||||
|
|
||||||
|
export type BindingCompletion = (context: CompletionContext) => {
|
||||||
|
from: number
|
||||||
|
options: Completion[]
|
||||||
|
} | null
|
||||||
|
|
||||||
|
export type BindingCompletionOption = Completion
|
|
@ -0,0 +1 @@
|
||||||
|
export * from "./bindings"
|
|
@ -1,10 +1,3 @@
|
||||||
export interface BindingCompletion {
|
|
||||||
section: {
|
|
||||||
name: string
|
|
||||||
}
|
|
||||||
label: string
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface EnrichedBinding {
|
export interface EnrichedBinding {
|
||||||
runtimeBinding: string
|
runtimeBinding: string
|
||||||
readableBinding: string
|
readableBinding: string
|
||||||
|
|
44
yarn.lock
44
yarn.lock
|
@ -2834,16 +2834,26 @@
|
||||||
dependencies:
|
dependencies:
|
||||||
"@bull-board/api" "5.10.2"
|
"@bull-board/api" "5.10.2"
|
||||||
|
|
||||||
"@codemirror/autocomplete@^6.0.0", "@codemirror/autocomplete@^6.7.1":
|
"@codemirror/autocomplete@6.9.0":
|
||||||
version "6.7.1"
|
version "6.9.0"
|
||||||
resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.7.1.tgz#3364799b78dff70fb8f81615536c52ea53ce40b2"
|
resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.9.0.tgz#1a1e63122288b8f8e1e9d7aff2eb39a83e04d8a9"
|
||||||
integrity sha512-hSxf9S0uB+GV+gBsjY1FZNo53e1FFdzPceRfCfD1gWOnV6o21GfB5J5Wg9G/4h76XZMPrF0A6OCK/Rz5+V1egg==
|
integrity sha512-Fbwm0V/Wn3BkEJZRhr0hi5BhCo5a7eBL6LYaliPjOSwCyfOpnjXY59HruSxOUNV+1OYer0Tgx1zRNQttjXyDog==
|
||||||
dependencies:
|
dependencies:
|
||||||
"@codemirror/language" "^6.0.0"
|
"@codemirror/language" "^6.0.0"
|
||||||
"@codemirror/state" "^6.0.0"
|
"@codemirror/state" "^6.0.0"
|
||||||
"@codemirror/view" "^6.6.0"
|
"@codemirror/view" "^6.6.0"
|
||||||
"@lezer/common" "^1.0.0"
|
"@lezer/common" "^1.0.0"
|
||||||
|
|
||||||
|
"@codemirror/autocomplete@^6.0.0":
|
||||||
|
version "6.18.4"
|
||||||
|
resolved "https://registry.yarnpkg.com/@codemirror/autocomplete/-/autocomplete-6.18.4.tgz#4394f55d6771727179f2e28a871ef46bbbeb11b1"
|
||||||
|
integrity sha512-sFAphGQIqyQZfP2ZBsSHV7xQvo9Py0rV0dW7W3IMRdS+zDuNb2l3no78CvUaWKGfzFjI4FTrLdUSj86IGb2hRA==
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/language" "^6.0.0"
|
||||||
|
"@codemirror/state" "^6.0.0"
|
||||||
|
"@codemirror/view" "^6.17.0"
|
||||||
|
"@lezer/common" "^1.0.0"
|
||||||
|
|
||||||
"@codemirror/commands@^6.2.4":
|
"@codemirror/commands@^6.2.4":
|
||||||
version "6.2.4"
|
version "6.2.4"
|
||||||
resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.2.4.tgz#b8a0e5ce72448c092ba4c4b1d902e6f183948aec"
|
resolved "https://registry.yarnpkg.com/@codemirror/commands/-/commands-6.2.4.tgz#b8a0e5ce72448c092ba4c4b1d902e6f183948aec"
|
||||||
|
@ -2893,6 +2903,13 @@
|
||||||
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.2.0.tgz#a0fb08403ced8c2a68d1d0acee926bd20be922f2"
|
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.2.0.tgz#a0fb08403ced8c2a68d1d0acee926bd20be922f2"
|
||||||
integrity sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA==
|
integrity sha512-69QXtcrsc3RYtOtd+GsvczJ319udtBf1PTrr2KbLWM/e2CXUPnh0Nz9AUo8WfhSQ7GeL8dPVNUmhQVgpmuaNGA==
|
||||||
|
|
||||||
|
"@codemirror/state@^6.5.0":
|
||||||
|
version "6.5.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@codemirror/state/-/state-6.5.2.tgz#8eca3a64212a83367dc85475b7d78d5c9b7076c6"
|
||||||
|
integrity sha512-FVqsPqtPWKVVL3dPSxy8wEF/ymIEuVzF1PK3VbUgrxXpJUSHQWWZz4JMToquRxnkw+36LTamCZG2iua2Ptq0fA==
|
||||||
|
dependencies:
|
||||||
|
"@marijn/find-cluster-break" "^1.0.0"
|
||||||
|
|
||||||
"@codemirror/theme-one-dark@^6.1.2":
|
"@codemirror/theme-one-dark@^6.1.2":
|
||||||
version "6.1.2"
|
version "6.1.2"
|
||||||
resolved "https://registry.yarnpkg.com/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz#fcef9f9cfc17a07836cb7da17c9f6d7231064df8"
|
resolved "https://registry.yarnpkg.com/@codemirror/theme-one-dark/-/theme-one-dark-6.1.2.tgz#fcef9f9cfc17a07836cb7da17c9f6d7231064df8"
|
||||||
|
@ -2912,6 +2929,15 @@
|
||||||
style-mod "^4.0.0"
|
style-mod "^4.0.0"
|
||||||
w3c-keyname "^2.2.4"
|
w3c-keyname "^2.2.4"
|
||||||
|
|
||||||
|
"@codemirror/view@^6.17.0":
|
||||||
|
version "6.36.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@codemirror/view/-/view-6.36.2.tgz#aeb644e161440734ac5a153bf6e5b4a4355047be"
|
||||||
|
integrity sha512-DZ6ONbs8qdJK0fdN7AB82CgI6tYXf4HWk1wSVa0+9bhVznCuuvhQtX8bFBoy3dv8rZSQqUd8GvhVAcielcidrA==
|
||||||
|
dependencies:
|
||||||
|
"@codemirror/state" "^6.5.0"
|
||||||
|
style-mod "^4.1.0"
|
||||||
|
w3c-keyname "^2.2.4"
|
||||||
|
|
||||||
"@colors/colors@1.6.0", "@colors/colors@^1.6.0":
|
"@colors/colors@1.6.0", "@colors/colors@^1.6.0":
|
||||||
version "1.6.0"
|
version "1.6.0"
|
||||||
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0"
|
resolved "https://registry.yarnpkg.com/@colors/colors/-/colors-1.6.0.tgz#ec6cd237440700bc23ca23087f513c75508958b0"
|
||||||
|
@ -4133,6 +4159,11 @@
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tar "^6.1.11"
|
tar "^6.1.11"
|
||||||
|
|
||||||
|
"@marijn/find-cluster-break@^1.0.0":
|
||||||
|
version "1.0.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/@marijn/find-cluster-break/-/find-cluster-break-1.0.2.tgz#775374306116d51c0c500b8c4face0f9a04752d8"
|
||||||
|
integrity sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==
|
||||||
|
|
||||||
"@mongodb-js/saslprep@^1.1.5":
|
"@mongodb-js/saslprep@^1.1.5":
|
||||||
version "1.1.7"
|
version "1.1.7"
|
||||||
resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz#d1700facfd6916c50c2c88fd6d48d363a56c702f"
|
resolved "https://registry.yarnpkg.com/@mongodb-js/saslprep/-/saslprep-1.1.7.tgz#d1700facfd6916c50c2c88fd6d48d363a56c702f"
|
||||||
|
@ -19961,6 +19992,11 @@ style-mod@^4.0.0:
|
||||||
resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.3.tgz#136c4abc905f82a866a18b39df4dc08ec762b1ad"
|
resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.0.3.tgz#136c4abc905f82a866a18b39df4dc08ec762b1ad"
|
||||||
integrity sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw==
|
integrity sha512-78Jv8kYJdjbvRwwijtCevYADfsI0lGzYJe4mMFdceO8l75DFFDoqBhR1jVDicDRRaX4//g1u9wKeo+ztc2h1Rw==
|
||||||
|
|
||||||
|
style-mod@^4.1.0:
|
||||||
|
version "4.1.2"
|
||||||
|
resolved "https://registry.yarnpkg.com/style-mod/-/style-mod-4.1.2.tgz#ca238a1ad4786520f7515a8539d5a63691d7bf67"
|
||||||
|
integrity sha512-wnD1HyVqpJUI2+eKZ+eo1UwghftP6yuFheBqqe+bWCotBjC2K1YnteJILRMs3SM4V/0dLEW1SC27MWP5y+mwmw==
|
||||||
|
|
||||||
stylus-lookup@^3.0.1:
|
stylus-lookup@^3.0.1:
|
||||||
version "3.0.2"
|
version "3.0.2"
|
||||||
resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd"
|
resolved "https://registry.yarnpkg.com/stylus-lookup/-/stylus-lookup-3.0.2.tgz#c9eca3ff799691020f30b382260a67355fefdddd"
|
||||||
|
|
Loading…
Reference in New Issue