在摩纳哥编辑器的上下文菜单中禁用剪切和复制

Disable Cut and Copy in context menu in Monaco editor

我正在使用 monaco-editor,我看到在更高版本的上下文菜单中添加了剪切和复制功能。我想从上下文菜单中删除这两个选项。请告诉我如何实现它?

使用 CSS

隐藏单个项目

我在浏览器中试过这段代码,它成功了。

// Hide from cut on
.context-view li.action-item:nth-child(n + 9) {
    display: none !important;
}

// Show command palette
.context-view li.action-item:last-child {
  display: flex !important;
}

使用 API

禁用整个菜单
monacoOptions = {
  // other options
  contextmenu: false
}

请参阅 IEditorConstructionOptions > contextmenu

上的文档

完整代码

import * as actions from "monaco-editor/esm/vs/platform/actions/common/actions";

let menus = actions.MenuRegistry._menuItems
let contextMenuEntry = [...menus].find(entry => entry[0]._debugName == "EditorContext")
let contextMenuLinks = contextMenuEntry[1]

let removableIds = ["editor.action.clipboardCopyAction", "editor.action.clipboardPasteAction"]

let removeById = (list, ids) => {
  let node = list._first
  do {
    let shouldRemove = ids.includes(node.element?.command?.id)
    if (shouldRemove) { list._remove(node) }
  } while ((node = node.next))
}

removeById(contextMenuLinks, removableIds)

演练

您可以从 actions.js 中的 MenuRegistry 访问可用的菜单功能:

import * as actions from "monaco-editor/esm/vs/platform/actions/common/actions"
let menus = actions.MenuRegistry._menuItems

这将提供所有菜单类型的列表:即
["MenubarEditMenu", "CommandPalette", "EditorContext", ...]

要具体访问和修改上下文菜单,我们可以在菜单图中找到它:

let contextMenuEntry = [...menus].find(entry => entry[0]._debugName == "EditorContext")
let contextMenuLinks = contextMenuEntry[1]

菜单项的类型为 LinkedList,其中每个 node 包含一个 element 以及对 prevnext 节点的引用,但是它带有一些实用方法,可以更轻松地进行推理。

所以如果你想列出所有命令,你可以这样做:

let allCommandIds = [...contextMenuLinks].map(el => el.command?.id)

使用它,确定您要提前提取的命令列表 - 在我们的例子中:

let removableIds = [
  "editor.action.clipboardCopyAction",
  "editor.action.clipboardPasteAction",
]

接下来我们需要识别并删除具有这些 ID 的节点。迭代器 returns node.<b>element</b>, but the _remove() 函数接受整个节点,因此我们必须进行与之前略有不同的迭代。这是一个循环遍历所有节点并删除每个节点的函数 if

然后我们将获取要删除的所有节点:

let removeById = (list, ids) => {
  let node = list._first;
  do {
    let shouldRemove = ids.includes(node.element?.command?.id)
    if (shouldRemove) { list._remove(node) }
  } while ((node = node.next))
}

然后这样调用:

removeById(contextMenuLinks, removableIds)

演示

进一步阅读

隐藏没有 CSS

的项目

以下内容对我有用,改编自 KyleMit 的 ,但如上所述对我不起作用。

import * as actions from 'monaco-editor/esm/vs/platform/actions/common/actions';

const idsToRemove = ['editor.action.clipboardCopyAction', 'editor.action.clipboardCutAction'];
actions.MenuRegistry._menuItems[1] = actions.MenuRegistry._menuItems[1]
        .filter(menuItem => !menuItem.command || !idsToRemove.includes(menuItem.command.id));