Monaco Editor跳转定义时如何下划线完整文本?
Monaco Editor:让带空格的对象完整支持Ctrl悬浮高亮与跳转定义
要解决带空格的对象(如"Hello world")无法被完整识别为可跳转单元的问题,核心是修改Monaco对"单词"的识别规则,同时调整定义提供者的范围匹配逻辑,具体需要做以下几项设置:
1. 自定义语言的词法规则(Tokenization)
Monaco默认会按空格分割token,你需要在自定义语言的tokenizer中,把带空格的目标对象标记为单个token。比如针对特定文本添加匹配规则:
const myLangTokenizer = { root: [ // 直接匹配带空格的目标文本,标记为标识符类型 [/Hello world/, 'identifier'], // 如果是带引号的带空格字符串,也可以单独匹配 [/"([^"]+)"/, 'string'], // 保留原有其他词法规则... ] }; monaco.languages.setMonarchTokensProvider('myCustomLang', myLangTokenizer);
这样编辑器会把整个"Hello world"当成一个独立的语法单元,而非两个分割的单词。
2. 配置wordPattern定义完整单词范围
Monaco的语言配置里的wordPattern属性决定了编辑器识别为"单词"的字符序列。默认规则不包含空格,需要修改它来允许空格存在于单词中:
monaco.languages.setLanguageConfiguration('myCustomLang', { // 自定义正则,允许单词包含空格,可根据需求调整精度 wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?]+)(\s+[^\`\~\!\@\#\$\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?]+)*/ });
这个规则会告诉编辑器,包含空格的连续目标序列属于一个完整的单词,Ctrl悬浮时就会选中整个对象。
3. 调整DefinitionProvider的范围匹配逻辑
在你的DefinitionProvider实现中,需要基于自定义的单词规则获取完整的文本范围,确保跳转定义的范围覆盖整个带空格的对象:
monaco.languages.registerDefinitionProvider('myCustomLang', { provideDefinition: (model, position) => { // 使用自定义正则获取当前位置的完整单词范围 const targetRange = model.getWordRangeAtPosition(position, /Hello world/); if (!targetRange) return null; const targetText = model.getValueInRange(targetRange); // 这里添加你的定义查找逻辑,返回对应的定义位置 return { uri: monaco.Uri.parse('file:///your-target-file.js'), range: new monaco.Range(1, 1, 1, targetText.length) }; } });
VS Code能实现该功能,是因为它针对内置语言预设了对应的词法规则和wordPattern,而Monaco作为独立编辑器,需要你手动为自定义语言配置这些规则。
内容的提问来源于stack exchange,提问作者Dmytro Golysh
相关产品推荐
相关产品推荐

