在有多个摩纳哥编辑器的情况下悬停提供者

问题描述 投票:0回答:1

我在 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 的正确方法是什么?

monaco-editor
1个回答
0
投票

已经过去几年了,但我最近遇到了同样的问题,并找到了一个解决方案,当您有 2 个以上 Monaco 编辑器时,可以可靠地防止悬停重复。

解决方案

为了解决这个问题,我引入了一种机制来跟踪当前悬停的 Monaco 模型,并仅显示该模型的悬停内容。以下是实施方法:

  1. 使用 useRef 来存储悬停的 Monaco 模型的 id:
const hoveredMonacoModelId = useRef<string | null>(null);
  1. 为每个编辑器配置
    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));
  }}
/>;

  1. 在注册悬停提供程序的
    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]);

这样做可以确保悬停提供程序仅针对相关编辑器的模型激活。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.