Sublime Forum

Can I send a menu button ID to my code?

#1

Forgive the newbishness of my questions. I am a (very) amateur coder and a lot of this is new. It appears as though, for a menu item to function, it has to reference a class. Then whatever you set up the class to do will happen when you click the button. This means one class per button.

What I was wanting to do was to make one class that contained the code for lots of buttons, with a simple if/elseif to trigger different behavior depending on which button was clicked.

Specifically, I am trying to create a menu of code snippets. I realize this is not the ordinary way code snippets work, but we have so many of them it’s just impossible to remember without a menu showing them all. So I wanted to set up some code that would select the snippet you wanted based on which button you clicked. Creating a separate class for each one is very doable. They are really short. But this would be more efficient, and could allow us to more dynamically add and change code snippets.

In fact it would be great if the code itself could dynamically set up the buttons needed, rather than having to manually add another button to the Main.sublime-menu file. But that may not be possible either.

Thanks for any suggestions :slight_smile:

0 Likes

#2

If you open the command palette and type snippet: Sublime Text will list to you all available snippets:

0 Likes

#3

We currently use a really old version of HTML Kit for our coding. It has very versatile plug-in functionality which is why we have never moved away from it. But there are certain more modern features we would like that it doesn’t have so we have been looking for alternatives.
We have a whole bunch of menus set up with code snippets of various categories, and adding them all up I am guessing we have at least 500 snippets through all the menus. It is very fast to be able to click twice to get to any snippet. I cannot see that working well using the existing snippet functionality.
Also, many of our snippets are a bit more than simple copy and paste a chunk of code. Many will surround selections with things, or perform other transformations on selected text.

Being able to define a certain functionality, whether it is a simple insert, or a surround, or something else, then changing the specifics of what happens based on a simple if/elseif depending on the ID of the button clicked, would really be ideal for us.

0 Likes

#4

Technically speaking, plugin classes that you create are generally creating a Command of some sort (TextCommand, WindowCommand or ApplicationCommand), which has a specific name, and which can be executed by referencing it by name, such as:

  1. From a menu item (Main menu or context menu)
  2. From a key binding
  3. From an entry in a command palette

To do that, your command class would take an argument that allows it to know how you want it to proceed, and then you pass the argument when you bind the button in the menu.

As a simple example:

import sublime
import sublime_plugin


class ExampleCommand(sublime_plugin.TextCommand):
    def run(self, edit, button):
        if button == "first":
            print("The first button")
        elif button == "second":
            print("The second button")
        else:
            print("Unknown button")

This creates a command named example (it’s based on the name of the class) which requires you to pass it an argument named button that tells it what to do.

In the menu, you would specify the name of the command and the arguments to pass. For example:

{
    "caption": "The first thing",
    "command": "example",
    "args": { "button": "first" }
}

Of course, you could use a name for the argument that was more descriptive than button, it could be a number instead of a string, and so on.

Note that when you define a command like this, it absolutely requires that you pass it the button argument; If you forget, seemingly nothing will happen, but you’ll see something like this in the console:

Traceback (most recent call last):
  File "/home/tmartin/local/sublime_text_3_3141/sublime_plugin.py", line 818, in run_
    return self.run(edit)
TypeError: run() missing 1 required positional argument: 'button'
1 Like

#5

That may be exactly what I am needing! Thank you I will play around with it now!

0 Likes