首页 > 其他分享 >在 Monaco Editor 中自定义右键菜单并支持多级菜单

在 Monaco Editor 中自定义右键菜单并支持多级菜单

时间:2024-08-23 11:54:14浏览次数:8  
标签:菜单 const 自定义 label 右键 id editor

Monaco Editor 中自定义右键菜单能够提供更灵活的功能选项。以下是如何在 Monaco Editor 中实现自定义右键菜单,并支持多级菜单的步骤及关键代码示例。

1. 初始化 Monaco Editor 实例

首先,需要初始化 Monaco Editor 实例,并设置基本的编辑器配置。

const initEditor = () => {
  if (monacoEditorRef.value) {
    editor = monaco.editor.create(monacoEditorRef.value, {
      value: props.modelValue,
      language: props.language,
      theme: props.theme,
      ...props.options,
    });
    // 其他初始化代码...
  }
};
2. 设置自定义右键菜单

为了自定义右键菜单,我们需要利用 MenuRegistryMenuId 来注册自定义的菜单项。以下是添加自定义菜单和子菜单的关键步骤。

const setupContextMenuFeature = (editor: monaco.editor.IStandaloneCodeEditor) => {
  const originalMenus = new Map<MenuId, LinkedList>();
  
  // 备份默认菜单
  MenuRegistry._menuItems.forEach((list, id) => {
    originalMenus.set(id, list);
  });

  // 添加自定义菜单项
  addActionWithSubmenus(editor, {
    title: 'AI 助手',
    context: 'EditorAIAssistantContext',
    group: 'navigation',
    order: 1,
    actions: [
      { id: 'explain-code', label: '解释代码', run: explainCode },
      { id: 'generate-unit-test', label: '生成单元测试', run: generateUnitTest },
      { id: 'generate-comments', label: '生成注释', run: generateComments },
      { id: 'provide-optimization-suggestions', label: '生成优化建议', run: provideOptimizationSuggestions },
    ],
  });

  // 恢复默认菜单项
  originalMenus.forEach((list, id) => {
    MenuRegistry._menuItems.set(id, list);
  });
};
3. 添加具有子菜单的菜单项

通过 addActionWithSubmenus 函数,可以为右键菜单添加子菜单项。以下是实现子菜单的代码。

const addActionWithSubmenus = (
  editor: monaco.editor.IStandaloneCodeEditor,
  descriptor: {
    title: string;
    context: string;
    group: string;
    order: number;
    actions: { run: () => void; label: string; id: string }[];
  },
) => {
  const submenuId = new MenuId(descriptor.context);
  const submenuList = new LinkedList();
  MenuRegistry._menuItems.set(submenuId, submenuList);

  descriptor.actions.forEach((action, index) => {
    editor.addAction({
      id: action.id,
      label: action.label,
      run: action.run,
      contextMenuOrder: index,
      contextMenuGroupId: descriptor.context,
    });
    const actionId = editor
      .getSupportedActions()
      .find((a) => a.label === action.label && a.id.endsWith(action.id))!.id;

    const contextMenuItems = MenuRegistry._menuItems.get(MenuId.EditorContext) as LinkedList;
    const item = popItem(contextMenuItems, actionId);
    if (item) {
      submenuList.push(item);
    }
  });

  const contextMenuItems = MenuRegistry._menuItems.get(MenuId.EditorContext) as LinkedList;
  contextMenuItems.push({
    group: descriptor.group,
    order: descriptor.order,
    submenu: submenuId,
    title: descriptor.title,
  });
};
4. 从菜单中移除并恢复默认项

在自定义菜单项时,可能需要从默认菜单中移除一些项,以下是处理这部分的代码。

const popItem = (items: LinkedList, id: string): any => {
  let node = items._first;
  while (node) {
    if (node.element?.command?.id === id) {
      items._remove(node);
      return node.element;
    }
    node = node.next;
  }
};
5. 实现菜单项的功能

自定义的菜单项可以绑定特定的功能。以下是一些示例功能的实现代码:

function explainCode() {
  alert('解释代码功能正在开发中...');
}

function generateUnitTest() {
  alert('生成单元测试功能正在开发中...');
}

function generateComments() {
  alert('生成注释功能正在开发中...');
}

function provideOptimizationSuggestions() {
  alert('优化建议功能正在开发中...');
}

总结

通过上述步骤,你可以在 Monaco Editor 中添加自定义的右键菜单,并支持多级菜单。关键点在于使用 MenuRegistryMenuId 来操作菜单项,并通过 LinkedList 管理菜单的层级结构。这使得你可以根据需要扩展编辑器的功能,并提供更丰富的用户交互体验。

标签:菜单,const,自定义,label,右键,id,editor
From: https://blog.csdn.net/weixin_48576413/article/details/141462381

相关文章

  • 自定义安装Nginx
    nginx下载地址:https://nginx.org/download/1.下载wgethttps://nginx.org/download/nginx-1.18.0.tar.gz2.安装依赖yum-yinstallgccgcc-c++makeautomakeautoconfpcrepcre-develzlibzlib-developensslopenssl-devellibtool3.解压tar-vxfnginx-1.18.0.tar.......
  • 自定义安装Mysql版本
    自定义安装Mysql版本mysql下载地址:https://downloads.mysql.com/archives/community/1.下载wgethttps://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.28-1.el7.x86_64.rpm-bundle.tar--2024-08-2010:15:39--https://downloads.mysql.com/archives/get/p/23/......
  • 关于在得帆云数据中台如何自定义函数
    UDF使用示例场景说明:使用udf编写一个函数Unit_Conversion(value)。在函数中根据value的值进行单位转化,并进行类型转化。1、导入依赖在pom.xml中将如下依赖进行导入。<dependency><groupId>org.apache.hive</groupId><artifactId>hive-exec<......
  • WPF 模拟UWP原生窗口样式——亚克力|云母材质、自定义标题栏样式、原生DWM动画 (附我封
    先看一下最终效果,左图为使用亚克力材质并添加组合颜色的效果;右图为MicaAlt材质的效果。两者都自定义了标题栏并且最大限度地保留了DWM提供的原生窗口效果(最大化最小化、关闭出现的动画、窗口阴影、拖拽布局器等)。接下来把各部分的实现一个个拆开来讲讲。一、使用窗口材质特......
  • 探索HarmonyOS中的列表组件及其自定义特性
    在现代移动应用中,List组件是数据列表的关键元素。HarmonyOS中的List组件不仅具备传统的列表功能,还提供了丰富的自定义选项,允许开发者根据需求灵活调整列表的行为和外观展示。本文将探讨HarmonyOS中列举组件的自定义特性,包括自定义项布局、动态加载数据、多列布局、拖拽排序......
  • 织梦dedecms二级菜单中判断子菜单标签怎么用
    在织梦DeDeCMS中,实现二级菜单通常涉及到使用织梦特有的标签来动态生成菜单结构。下面是如何在二级菜单中使用织梦标签来判断子菜单的存在,并据此显示或隐藏子菜单的方法。1.准备工作确定主菜单:首先确定您想要作为主菜单的栏目ID。创建子菜单:在后台为相应的主菜单创建子栏目。......
  • QT自定义结构体的传递
    方法1:使用Q_DECLARE_METATYPE(TestResult)进行声明1.1声明#ifndefTESTRESULT_H#defineTESTRESULT_H#include<QDateTime>#include<QString>#include<QMetaType>//用于测试时更新内容,作为结果导出的依据classTestResult{public:int_nid=0;int_coun......
  • 织梦dedeCMS怎么使用arclist标签调用自定义字段
    {dede:arclistrow='10'titlelen='24'orderby='pubdate'idlist=''col='2'}[field:textlink/]([field:pubdatefunction=MyDate('m-d',@me)/])<br/>{/dede:arclist}row=‘10’返回文档列表总数typeid=‘’栏目ID......
  • mybatis-plus配置自定义sqlInjector(使用InsertBatchSomeColumn),出现Invalid bound stat
    项目一开始未引入mybatis-plus,使用的是mybatis,配置文件为xml,有一个配置类中配置了SqlSessionFactory的相关内容。引入mybatis-plus后,想使用InsertBatchSomeColumn遇到Invalidboundstatement(notfound),多处配置发现没有效果并依旧报错,最终在刚才的配置类中的SqlSessionFact......
  • 树形菜单节点上下移动(同级别)
     在软件开发过程中,有遇到过树形菜单节点排序问题,如节点上移、节点下移。以下是一种实现方式,请工程师们审查是否合理!     publicclassNodeInfoEntity{///<summary>///id///</summary>[Column(Name="id")]publicstringId{......