我在 Monaco Editor 之上构建了一个组件
ResizableMonacoEditor
。在index.tsx
,我们有
import * as monaco from 'monaco-editor';
const MonacoEditor = lazy(() => import('react-monaco-editor'));
monaco.languages.register({ id: "mySpecialLanguage", extensions: [], aliases: [], mimetypes: [], });
class ResizableMonacoEditor extends React.Component {
_handleEditorDidMount(editor, monaco) {
... ...
monaco.languages.registerHoverProvider("mySpecialLanguage", {
provideHover: (model, position, token) => {
return {
range: new monaco.Range(1, 1, model.getLineCount(), model.getLineMaxColumn(model.getLineCount())),
contents: [
{ value: '**SOURCE**' }
]
};
}
});
}
... ...
render() {
return <MonacoEditor {...this.props} editorDidMount={this._handleEditorDidMount.bind(this)} />
}
}
当页面上只有 1 个
ResizableMonacoEditor
时,它就可以工作。现在,我想在一页上有两个ResizableMonacoEditor
。他们都应该在mySpecialLangauge
举办节目。
然后,我意识到每个编辑器都注册了一个hoverProvider。因此,当我将鼠标悬停在一个编辑器中的文本上时,消息中会显示两个
**SOURCE**
。但是,我认为只有编辑器注册的hoverProvider才应该被执行。
有谁知道在多个摩纳哥编辑器的情况下组织语言、编辑器、模型和 registerHoverProvider 的正确方法是什么?
已经过去几年了,但我最近遇到了同样的问题,并找到了一个解决方案,当您有 2 个以上 Monaco 编辑器时,可以可靠地防止悬停重复。
为了解决这个问题,我引入了一种机制来跟踪当前悬停的 Monaco 模型,并仅显示该模型的悬停内容。以下是实施方法:
const hoveredMonacoModelId = useRef<string | null>(null);
onMouseMove
和 onMouseLeave
事件回调以适当设置引用。onMouseEnter
事件回调会更好,但不幸的是摩纳哥没有公开这种回调。和 onMouseMove
似乎是最好的选择。这是低效的,因为它触发的次数比需要的多得多,但因为我们只是设置一个引用,所以影响可以忽略不计。import { Editor } from '@monaco-editor/react';
<Editor
{...otherProps}
onMount={(editor) => {
const monacoModelId = editor.getModel()?.id ?? null;
editor.onMouseMove(() => (hoveredMonacoModelId.current = monacoModelId));
editor.onMouseLeave(() => (hoveredMonacoModelId.current = null));
}}
/>;
useEffect
内,将 hoveredMonacoModelId
的当前值与悬停模型的 id
进行比较。import { useMonaco } from '@monaco-editor/react';
const monaco = useMonaco();
useEffect(() => {
if (!monaco) return;
const hoverProvider = monaco.languages.registerHoverProvider('json', {
provideHover: (hoverModel, position) => {
// return early when not hovering the expected model
if (hoverModel.id !== hoveredMonacoModelId.current) return null;
return {
contents: [{ value: '**Example Hover Content**' }],
};
},
});
return () => hoverProvider.dispose();
}, [monaco]);
这样做可以确保悬停提供程序仅针对相关编辑器的模型激活。