如何在Monaco Editor中禁用JS/TS额外关键词并实现自定义语言智能提示
问题1:禁用JS/TS额外关键词,仅保留自定义内容
首先,你遇到的问题大概率是两个原因导致的:一是自定义类型声明存在语法错误,二是noLib选项的生效需要配合正确的库加载逻辑。
先看你代码里的函数声明:
'declare function Foo(a: number,b: number, name: string (optional)) :void'
这里的(optional)不符合TypeScript语法规范,正确的可选参数写法应该是name?: string。语法错误会让TypeScript语言服务无法正确解析你的自定义库,进而 fallback 到默认的JS/TS内置类型,这就是额外关键词仍会显示的原因。
修正语法后,再通过setExtraLibs替换addExtraLib(addExtraLib是追加自定义库,而setExtraLibs会直接替换所有自定义库),同时调用revalidate()刷新语言服务,确保noLib: true完全生效:
require.config({paths: {'vs': 'lib/package/min/vs'}}); require(['vs/editor/editor.main'], function() { let editor = monaco.editor.create(document.getElementById('editor'), { language: 'typescript', minimap: {enabled: false}, }); // 用setExtraLibs确保仅加载自定义内容 monaco.languages.typescript.typescriptDefaults.setExtraLibs([ 'declare function Foo(a: number, b: number, name?: string): void;', 'const someString: string;', ].join('\n')); monaco.languages.typescript.typescriptDefaults.setCompilerOptions({ noLib: true, allowNonTsExtensions: true, target: 'esnext', // 可选,避免默认目标环境的类型干扰 }); // 刷新语言服务,让配置生效 monaco.languages.typescript.typescriptDefaults.revalidate(); editor.updateOptions({fontSize: 20}); });
如果设置后仍有问题,可以尝试清空默认库路径彻底隔离内置类型:
monaco.languages.typescript.typescriptDefaults.setLibFileName('');
问题2:使用自定义语言实现函数预览(不依赖JS/TS)
当然可以!Monaco Editor完全支持自定义语言,你只需要分四步实现:注册语言ID、配置语法高亮、添加智能提示、注册参数预览服务。
下面是一个完整的可运行示例:
require.config({paths: {'vs': 'lib/package/min/vs'}}); require(['vs/editor/editor.main'], function() { // 1. 注册自定义语言ID monaco.languages.register({ id: 'myCustomLang' }); // 2. 配置语法高亮(标记关键词、函数名等) monaco.languages.setMonarchTokensProvider('myCustomLang', { keywords: ['Foo'], tokenizer: { root: [ // 匹配自定义关键词,标记为keyword样式 [/\b(Foo)\b/, 'keyword'], // 匹配变量名或函数调用 [/\w+/, 'identifier'], // 匹配括号、逗号等分隔符 [/[(),]/, 'delimiter'], // 匹配数字 [/\d+/, 'number'], ] } }); // 3. 注册智能提示 monaco.languages.registerCompletionItemProvider('myCustomLang', { provideCompletionItems: (model, position) => { return { suggestions: [ { label: 'Foo', kind: monaco.languages.CompletionItemKind.Function, documentation: '自定义业务函数,用于处理数值和字符串', insertText: 'Foo(${1:number}, ${2:number}, ${3?:string})', insertTextRules: monaco.languages.CompletionItemInsertTextRule.InsertAsSnippet } ] }; } }); // 4. 注册参数预览(函数签名提示) monaco.languages.registerSignatureHelpProvider('myCustomLang', { provideSignatureHelp: (model, position) => { // 仅在输入Foo(时触发提示 const textBeforeCursor = model.getValueInRange({ startLineNumber: position.lineNumber, startColumn: 1, endLineNumber: position.lineNumber, endColumn: position.column }); if (!textBeforeCursor.includes('Foo(')) { return null; } // 根据逗号数量判断当前激活的参数 const paramIndex = textBeforeCursor.split(',').length - 1; return { signatures: [ { label: 'Foo(a: number, b: number, name?: string): void', parameters: [ { label: 'a: number', documentation: '第一个数值参数,必填' }, { label: 'b: number', documentation: '第二个数值参数,必填' }, { label: 'name?: string', documentation: '可选字符串参数,用于标识名称' } ] } ], activeSignature: 0, activeParameter: paramIndex }; }, // 触发提示的字符 triggerCharacters: ['(', ','] }); // 创建编辑器,使用自定义语言 let editor = monaco.editor.create(document.getElementById('editor'), { language: 'myCustomLang', minimap: {enabled: false}, fontSize: 20 }); });
这个示例实现了:
- 自定义关键词
Foo的语法高亮 - 输入时的智能提示(输入
F会弹出Foo的提示项) - 输入
Foo(后自动显示参数预览,切换参数时同步更新当前参数的说明
你可以根据需求扩展语法规则、添加更多关键词/函数,或者优化参数位置的判断逻辑,让自定义语言更贴合你的业务场景。
内容的提问来源于stack exchange,提问作者vs88
相关产品推荐
相关产品推荐

