Add code mirror completions for snippets
This commit is contained in:
parent
cef0911950
commit
79ae159329
|
@ -83,8 +83,8 @@
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
// For handlebars only.
|
// Match decoration for HBS bindings
|
||||||
const bindStyle = new MatchDecorator({
|
const hbsMatchDeco = new MatchDecorator({
|
||||||
regexp: FIND_ANY_HBS_REGEX,
|
regexp: FIND_ANY_HBS_REGEX,
|
||||||
decoration: () => {
|
decoration: () => {
|
||||||
return Decoration.mark({
|
return Decoration.mark({
|
||||||
|
@ -95,12 +95,35 @@
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
const hbsMatchDecoPlugin = ViewPlugin.define(
|
||||||
let plugin = ViewPlugin.define(
|
|
||||||
view => ({
|
view => ({
|
||||||
decorations: bindStyle.createDeco(view),
|
decorations: hbsMatchDeco.createDeco(view),
|
||||||
update(u) {
|
update(u) {
|
||||||
this.decorations = bindStyle.updateDeco(u, this.decorations)
|
this.decorations = hbsMatchDeco.updateDeco(u, this.decorations)
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
decorations: v => v.decorations,
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
// Match decoration for snippets
|
||||||
|
const snippetMatchDeco = new MatchDecorator({
|
||||||
|
regexp: /snippets.[^\s(]+/g,
|
||||||
|
decoration: () => {
|
||||||
|
return Decoration.mark({
|
||||||
|
tag: "span",
|
||||||
|
attributes: {
|
||||||
|
class: "snippet-wrap",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
},
|
||||||
|
})
|
||||||
|
const snippetMatchDecoPlugin = ViewPlugin.define(
|
||||||
|
view => ({
|
||||||
|
decorations: snippetMatchDeco.createDeco(view),
|
||||||
|
update(u) {
|
||||||
|
this.decorations = snippetMatchDeco.updateDeco(u, this.decorations)
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
{
|
{
|
||||||
|
@ -142,7 +165,6 @@
|
||||||
|
|
||||||
const buildBaseExtensions = () => {
|
const buildBaseExtensions = () => {
|
||||||
return [
|
return [
|
||||||
...(mode.name === "handlebars" ? [plugin] : []),
|
|
||||||
drawSelection(),
|
drawSelection(),
|
||||||
dropCursor(),
|
dropCursor(),
|
||||||
bracketMatching(),
|
bracketMatching(),
|
||||||
|
@ -165,7 +187,10 @@
|
||||||
override: [...completions],
|
override: [...completions],
|
||||||
closeOnBlur: true,
|
closeOnBlur: true,
|
||||||
icons: false,
|
icons: false,
|
||||||
optionClass: () => "autocomplete-option",
|
optionClass: completion =>
|
||||||
|
completion.simple
|
||||||
|
? "autocomplete-option-simple"
|
||||||
|
: "autocomplete-option",
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
complete.push(
|
complete.push(
|
||||||
|
@ -191,18 +216,23 @@
|
||||||
view.dispatch(tr)
|
view.dispatch(tr)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
return false
|
return false
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// JS only plugins
|
||||||
if (mode.name === "javascript") {
|
if (mode.name === "javascript") {
|
||||||
|
complete.push(snippetMatchDecoPlugin)
|
||||||
complete.push(javascript())
|
complete.push(javascript())
|
||||||
if (!readonly) {
|
if (!readonly) {
|
||||||
complete.push(highlightWhitespace())
|
complete.push(highlightWhitespace())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// HBS only plugins
|
||||||
|
else {
|
||||||
|
complete.push(hbsMatchDecoPlugin)
|
||||||
|
}
|
||||||
|
|
||||||
if (placeholder) {
|
if (placeholder) {
|
||||||
complete.push(placeholderFn(placeholder))
|
complete.push(placeholderFn(placeholder))
|
||||||
|
@ -376,9 +406,12 @@
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Highlight bindings */
|
/* Highlight bindings and snippets */
|
||||||
.code-editor :global(.binding-wrap) {
|
.code-editor :global(.binding-wrap) {
|
||||||
color: var(--spectrum-global-color-blue-700);
|
color: var(--spectrum-global-color-blue-700) !important;
|
||||||
|
}
|
||||||
|
.code-editor :global(.snippet-wrap *) {
|
||||||
|
color: #61afef !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Completion popover */
|
/* Completion popover */
|
||||||
|
@ -407,7 +440,8 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Completion item container */
|
/* Completion item container */
|
||||||
.code-editor :global(.autocomplete-option) {
|
.code-editor :global(.autocomplete-option),
|
||||||
|
.code-editor :global(.autocomplete-option-simple) {
|
||||||
padding: var(--spacing-s) var(--spacing-m) !important;
|
padding: var(--spacing-s) var(--spacing-m) !important;
|
||||||
padding-left: calc(16px + 2 * var(--spacing-m)) !important;
|
padding-left: calc(16px + 2 * var(--spacing-m)) !important;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -415,9 +449,13 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
color: var(--spectrum-alias-text-color);
|
color: var(--spectrum-alias-text-color);
|
||||||
}
|
}
|
||||||
|
.code-editor :global(.autocomplete-option-simple) {
|
||||||
|
padding-left: var(--spacing-s) !important;
|
||||||
|
}
|
||||||
|
|
||||||
/* Highlighted completion item */
|
/* Highlighted completion item */
|
||||||
.code-editor :global(.autocomplete-option[aria-selected]) {
|
.code-editor :global(.autocomplete-option[aria-selected]),
|
||||||
|
.code-editor :global(.autocomplete-option-simple[aria-selected]) {
|
||||||
background: var(--spectrum-global-color-blue-400);
|
background: var(--spectrum-global-color-blue-400);
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
@ -433,6 +471,9 @@
|
||||||
font-family: var(--font-sans);
|
font-family: var(--font-sans);
|
||||||
text-transform: capitalize;
|
text-transform: capitalize;
|
||||||
}
|
}
|
||||||
|
.code-editor :global(.autocomplete-option-simple .cm-completionLabel) {
|
||||||
|
text-transform: none;
|
||||||
|
}
|
||||||
|
|
||||||
/* Completion item type */
|
/* Completion item type */
|
||||||
.code-editor :global(.autocomplete-option .cm-completionDetail) {
|
.code-editor :global(.autocomplete-option .cm-completionDetail) {
|
||||||
|
|
|
@ -102,6 +102,29 @@ export const getHelperCompletions = mode => {
|
||||||
}, [])
|
}, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const snippetAutoComplete = snippets => {
|
||||||
|
return function myCompletions(context) {
|
||||||
|
if (!snippets?.length) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
const word = context.matchBefore(/\w*/)
|
||||||
|
if (word.from == word.to && !context.explicit) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
from: word.from,
|
||||||
|
options: snippets.map(snippet => ({
|
||||||
|
label: `snippets.${snippet.name}`,
|
||||||
|
type: "text",
|
||||||
|
simple: true,
|
||||||
|
apply: (view, completion, from, to) => {
|
||||||
|
insertSnippet(view, from, to, completion.label)
|
||||||
|
},
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const bindingFilter = (options, query) => {
|
const bindingFilter = (options, query) => {
|
||||||
return options.filter(completion => {
|
return options.filter(completion => {
|
||||||
const section_parsed = completion.section.name.toLowerCase()
|
const section_parsed = completion.section.name.toLowerCase()
|
||||||
|
@ -247,6 +270,21 @@ export const insertBinding = (view, from, to, text, mode) => {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const insertSnippet = (view, from, to, text, mode) => {
|
||||||
|
const parsedInsert = `${text}()`
|
||||||
|
let cursorPos = from + parsedInsert.length - 1
|
||||||
|
view.dispatch({
|
||||||
|
changes: {
|
||||||
|
from,
|
||||||
|
to,
|
||||||
|
insert: parsedInsert,
|
||||||
|
},
|
||||||
|
selection: {
|
||||||
|
anchor: cursorPos,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
export const bindingsToCompletions = (bindings, mode) => {
|
export const bindingsToCompletions = (bindings, mode) => {
|
||||||
const bindingByCategory = groupBy(bindings, "category")
|
const bindingByCategory = groupBy(bindings, "category")
|
||||||
const categoryMeta = bindings?.reduce((acc, ele) => {
|
const categoryMeta = bindings?.reduce((acc, ele) => {
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
getHelperCompletions,
|
getHelperCompletions,
|
||||||
jsAutocomplete,
|
jsAutocomplete,
|
||||||
hbAutocomplete,
|
hbAutocomplete,
|
||||||
|
snippetAutoComplete,
|
||||||
EditorModes,
|
EditorModes,
|
||||||
bindingsToCompletions,
|
bindingsToCompletions,
|
||||||
} from "../CodeEditor"
|
} from "../CodeEditor"
|
||||||
|
@ -98,6 +99,7 @@
|
||||||
...bindingCompletions,
|
...bindingCompletions,
|
||||||
...getHelperCompletions(EditorModes.JS),
|
...getHelperCompletions(EditorModes.JS),
|
||||||
]),
|
]),
|
||||||
|
snippetAutoComplete(snippets),
|
||||||
]
|
]
|
||||||
|
|
||||||
const getModeOptions = (allowHBS, allowJS) => {
|
const getModeOptions = (allowHBS, allowJS) => {
|
||||||
|
|
Loading…
Reference in New Issue