import ace from 'brace'; // import brace 必须在ace之后 import 'brace/ext/language_tools'; import 'brace/mode/yaml'; import 'brace/snippets/yaml'; import 'brace/theme/github'; import s from '../style.less'; import { noop } from 'lodash/fp'; import React, { useEffect, useRef } from 'react'; import AceEditor from 'react-ace'; import { useSnippets } from './custom-hooks'; let langTools = ace.acequire('ace/ext/language_tools'); const { snippetManager } = ace.acequire('ace/snippets'); const customSnippetText = [ 'snippet $snippet', '\t\\$snippet ${1:fieldName}: ${2:snippetId}', 'snippet $mockjs', '\t\\$mockjs ${1:fieldName}: ${2:mockVal}' ].join('\n') const customSnippet = snippetManager.parseSnippetFile(customSnippetText); snippetManager.register(customSnippet, 'yaml'); export default function Editor({ value = '', width = '100%', height = '100vh', onChange = noop, onClose = noop, readOnly = false, children = null, }) { const snippets = useSnippets() const snippetListRef = useRef(null) useEffect(() => { snippetListRef.current = snippets.map(s => ({ caption: s.name, snippet: `${s.name}|${s.id}`, meta: 'custom snippet', score: 100, })) }, [snippets]) useEffect(() => { function onPressESC(evt) { if (evt.key === 'Escape') { onClose() evt.preventDefault() } } document.addEventListener('keydown', onPressESC) return () => { document.removeEventListener('keydown', onPressESC) } }, [onClose]) useEffect(() => { langTools.addCompleter({ getCompletions(editor, session, pos, prefix, cb) { const lineStr = session.getLine(pos.row); // 以$snippet开头 且光标在冒号后面 if ( /^\s*\$snippet\s+/.test(lineStr) && lineStr.includes(':') && lineStr.indexOf(':') < pos.column ) { cb(null, snippetListRef.current || []) return } cb(null, []) }, insertMatch: function (editor, data) { editor.forEachSelection(function () { editor.insert(data.caption) }) } }) }, []) return
{children}
}