先上图

代码有空在写进来,今天就这样
补全代码如下
// 代码参考了@codemirror/search
import { Decoration, EditorView, ViewPlugin, ViewUpdate, type DecorationSet } from '@codemirror/view'
import { Facet, combineConfig } from '@codemirror/state'
//#region 定义插件
type HighlightOptions = {
getKeywords: () => string[];
}
const defaultHighlightOptions: HighlightOptions = {
getKeywords: () => []
}
const highlightConfig = Facet.define<HighlightOptions, Required<HighlightOptions>>({
combine(options: readonly HighlightOptions[]) {
return combineConfig(options, {})
}
})
const matchDeco = Decoration.mark({class: "cm-variableMatch"})
const matchHighlighter = ViewPlugin.fromClass(class {
decorations: DecorationSet
constructor(view: EditorView) {
this.decorations = this.getDeco(view)
}
generateRanges(text: string, keywords: string[]) {
const ret = [] as Array<{from: number; to: number}>
keywords.forEach(keyword => {
let index = 0
while((index = text.indexOf(`{{${keyword}}}`, index)) !== -1) {
ret.push({ from: index + 2, to: index + 2 + keyword.length })
index += 4 + keyword.length
}
})
return ret
}
update(update: ViewUpdate) {
if (update.docChanged || update.viewportChanged) {
this.decorations = this.getDeco(update.view)
}
}
getDeco(view: EditorView) {
const keywords = view.state.facet(highlightConfig).getKeywords()
const ranges = this.generateRanges(view.state.doc.toString(), keywords)
if (ranges.length) {
return Decoration.set(ranges.map(r => matchDeco.range(r.from, r.to)), true)
}
return Decoration.none
}
}, {
decorations: v => v.decorations
})
const defaultTheme = EditorView.baseTheme({
".cm-variableMatch": { color: "#1890FF" }
})
//#endregion
export default (options: HighlightOptions) => {
return [defaultTheme, matchHighlighter, highlightConfig.of(options)]
}
如果您觉得对您有帮助,请点赞哦:)