You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Monaco Editor自定义语言自动补全不触发(疑似分词器问题?语法高亮仅部分生效)

Monaco Editor自定义语言自动补全不触发(疑似分词器问题?语法高亮仅部分生效)

我来帮你排查这两个问题,先解决最棘手的自动补全失效,再搞定内置函数高亮的问题:

一、自动补全不触发的核心原因

你在registerCodeFrLanguage函数里的补全提供者代码有个致命的小错误:builtins变量未定义!

看你的代码,builtins数组是放在codeFrLanguage对象里的,但在补全回调里你直接写了builtins.map,这个变量在当前函数作用域里根本找不到,会悄悄抛出ReferenceError——这就是为什么你看不到console.log输出的原因,因为补全提供者压根没注册成功。

解决办法很简单,要么从codeFrLanguage里解构出builtins,要么直接引用codeFrLanguage.builtins:

export const registerCodeFrLanguage = (monaco) => {
    // 先把内置函数数组解构出来,避免作用域问题
    const { builtins } = codeFrLanguage;
    
    monaco.languages.register({ id: 'codefr' });
    monaco.languages.setMonarchTokensProvider('codefr', codeFrLanguage);
    monaco.languages.setLanguageConfiguration('codefr', codeFrConfig);

    monaco.languages.registerCompletionItemProvider('codefr', {
        // 补上'R'!你的内置函数Racine是以R开头的,之前的触发字符里没它
        triggerCharacters: [' ', '\n', ':', '.', '(', '[', 'A', 'R', 'S', 'V'],
        provideCompletionItems: (model, position) => {
            console.log("Completion provider called!", position);
            const word = model.getWordUntilPosition(position);
            const range = {
                startLineNumber: position.lineNumber,
                endLineNumber: position.lineNumber,
                startColumn: word.startColumn,
                endColumn: word.endColumn
            };
            const suggestions = builtins.map(builtin => ({
                label: builtin,
                kind: monaco.languages.CompletionItemKind.Function,
                insertText: builtin,
                range: range
            }));
            return { suggestions };
        }
    });
};

另外,测试的时候可以手动按Ctrl+Space强制触发补全,不管有没有触发字符,这样能快速验证提供者是否注册成功。

二、内置函数不高亮的问题

你的分词器逻辑本身没问题,但有个细节可能导致高亮失效:
Monaco默认主题里,'function'这个token通常是给用户自定义函数用的,内置函数需要用'builtin'或者'function.builtin'才能拿到正确的高亮样式。你可以先把token名称改成'keyword'测试,如果能高亮,就说明是token名称的问题,换成'builtin'即可:

// 修改tokenizer里的cases部分
cases: {
    '@keywords': 'keyword',
    '@typeKeywords': 'type',
    '@builtins': 'builtin', // 换成builtin试试
    '@default': 'identifier'
}

另外确认一下:你的ignoreCase设为false,输入的Racine、Abs和数组里的大小写完全一致(你示例里是对的,这个没问题)。

其他小提醒

  • 检查浏览器控制台的Errors标签页:有时候异步加载的代码报错会被隐藏,仔细看看有没有未捕获的错误;
  • 你的React组件里的重复注册检查逻辑是对的,避免了多次注册语言的问题。

按照上面的修改,应该就能解决这两个问题了!

备注:内容来源于stack exchange,提问作者nitoua

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.14 16:59:30