如何创建可与默认context_menu一起使用的独特弹出菜单?

时间:2019-05-31 05:04:25

标签: python python-3.x plugins sublimetext3

插件开发)( Sublime )( Python )(.sublime-menu)

我目前正在寻找一种创建唯一的context_menu的方法,该方法不依赖于任何现有的默认'.sublime-menu'文件。 我会使用常规的context_menu,但是我已经很好地填满了。而且我想为不同的菜单使用不同的按钮。

这是我当前的右键菜单:

我当前的context_menu:

My current context_menu

我想创建另一个类似于此菜单的动态菜单,但是依赖于main / context.sublime菜单,并且可以通过使用键/鼠标组合来激活< strong> ctrl + button4 (我已经设置好了)。

{
  "button": "button4",
  "count": 1,
  "modifiers": ["ctrl"],
  "command": "quick_click"
}

我已经将 show_popup_menu()视为一个选项,并已将 paste_from_history.py 文件用作一种参考。

类PasteFromHistoryCommand(sublime_plugin.TextCommand): 来自Sublime \ Packages \ Default.sublime-package.zip \ paste_from_history.py

但是,菜单似乎唯一要做的就是从列表中突出显示所选内容,并将其传递给文本变量,然后将其传递给文本命令“ paste”。

g_clipboard_history.push_text(text)
sublime.set_clipboard(text)
self.view.run_command("paste")

show_popup_menu(项目,on_done,标志)具有字段“ 项目”,“ on_done ”,。而且我不知道这些是什么意思或如何使用它们。

我尝试过这样的代码:(而且我也没有任何反馈)

class QuickClickCommand(sublime_plugin.TextCommand):
  def run(self, view):
    self.view.show_popup_menu (
      [
        "Select All",
        "Swap Case"
      ],
      [
        self.view.run_command("select_all"),
        self.view.run_command("swap_case")
      ],
      ["1", "2"]  // ← with or without this option
    )

但是当我使用以下代码时,►

class QuickClickCommand(sublime_plugin.TextCommand):
  def run(self, view):
    self.view.show_popup_menu (
      ["Item 1", "Item 2"], ["1", "2"]
    )

►我有一个包含2个项目的上下文菜单-按下后它们都不做任何事情。

一种上下文菜单:

A type of context menu

我尝试了几种组合-似乎没有任何效果,而且我找不到有关此主题的信息。

如您所见,我有一个插件:

类QuickClickCommand(sublime_plugin.TextCommand)

然后我通过选择 ctrl + button4

访问该插件
{
    "button": "button4",
    "count": 1,
    "modifiers": ["ctrl"],
    "command": "quick_click"
}

是否可以创建自己的quickclick.sublime-menu文件,还是使用默认的context_menu.sublime-menu卡住?

有关如何操作的任何链接,建议或解释 show_popup_menu(项目,on_done)用于赞赏

这是用户文档对此的评价:

在插入符号处显示一个弹出菜单,以在列表中选择一个项目。

on_done将被调用一次,并带有所选项目的索引。

如果取消了弹出菜单,则会使用参数-1调用on_done。

Items是一个字符串数组。

标记目前无法选择。

使用下面的代码:我得到以下结果。

class QuickClickCommand(sublime_plugin.TextCommand):
  def run(self, view):
    self.view.show_popup('Hello, <b>World!</b><br>
    <a href="moo">Click Me</a>', on_navigate=print)
    self.view.show_popup_menu (["Item 1", "Item 2"], ["1", "2"]) 

弹出一个菜单。

弹出菜单:

Popup Menu

一旦我选择了这2个项目中的任何一个,就会出现一个带有“ Hello World”和“ Click Me”链接的面板。

你好,世界!面板:

Hello, World! Panel

点击“点击我”(“ Hello,World”)会传播到控制台。

有没有一种方法可以使我的自定义菜单升华(除了将内容添加到灌输时可用的其他11种可能的菜单中),

感谢您的患者阅读本文,以及您可能花费任何时间回复我。

1 个答案:

答案 0 :(得分:0)

view.show_popup_menu()的文档中说:

API Help

也就是说,该方法将字符串列表作为第一个参数显示在菜单中,并在用户选择一个项目作为第二个参数时调用该函数;该函数将被传递给用户所选项目的索引。

在您的示例代码中,您的第二个参数不是函数,而是其他内容。您没有得到任何直接的反馈,但这仅仅是因为Sublime在尝试调用回调并失败时正在吞噬错误。

第三个参数对任何东西都没有影响,因为正如文档中概述的那样,即使它被认为是标志,当前也被忽略了。

您的问题还引用了使用此API端点的paste_from_history命令,相关代码行如下:

self.view.show_popup_menu(keys, lambda choice_index: self.paste_choice(choice_index))

这暗示第二个参数是一个函数(在本例中为lambda),该函数将提供用户选择项目时选择的索引。

由此带来的好处是,与标准菜单不同,当您使用view.show_popup_menu()时,只需在窗口的插入位置打开一个菜单以显示用户选项,当他们选择一个时,您会被告知他们选了哪一个。如果没有选择就关闭菜单,也会提示您(所选项目为-1,这不是有效的索引)。

如果要从这样的菜单中运行命令,则需要以下内容:

import sublime
import sublime_plugin


class QuickClickCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        items = [
            {"caption": "Echo stuff", "command": "echo", "args": {"a": True}},
            {"caption": "Select All", "command": "select_all"},
            {"caption": "Swap Case", "command": "swap_case"},
        ]
        self.view.show_popup_menu(
            [item["caption"] for item in items],
            lambda idx: self.pick(idx, items))

    def pick(self, idx, items):
        if idx >= 0:
            command = items[idx].get("command")
            args = items[idx].get("args")
            self.view.window().run_command(command, args)

首先,有一个您希望能够执行的命令列表,概述为指定caption(您要在菜单中看到的内容),command(实际要执行的命令)和args(命令可能碰到或需要的所有参数)。

我们调用show_popup_menu并使用列表推导将一个字符串列表传递给它,该字符串列表是列表中所有项目的标题。第二个参数是当用户取消菜单或选择项目时将调用的回调。我们指定应在给定用户选择的商品的索引以及商品的原始列表的情况下调用它。

选择一个项目时,将调用pick()并为其指定所选项目的索引。如果是-1,则用户关闭了菜单,因此我们什么也不做。否则,我们将使用提供的索引从原始项目列表中获取命令和参数(如果有),然后运行该命令。

这使用self.view.window().run_command()而不是self.view.run_command(),因为view只能执行修改缓冲区的命令;因此,通常最好使用window来运行命令,因为它可以运行所有命令。