Sublime Forum

Getting Started Questions

#1

I’m trying to get started with plugin development as there’s a need that doesn’t yet exist. So I’ve been searching for everything I can find and am running into a number of unexplained things that maybe someone can help with.

  1. I see references to examples in the Default package. This is great, however, when I open Default.sublime-package it’s been encoded in some format. I’ve not seen any mention of this and instead all the documentation (unofficial or official I’m not sure) says you can add Default packages to your project and just browse the *.py files. Searching for converting sublime-package to something else doesn’t seem to return anything else. How are these files packed or encoded and how can I browse the API and examples?

  2. There seems to be some variation in arguments for the run method. The skeleton plugin shows:
    def run(self, edit)
    However I’ve seen other examples that show:
    def run(self, view, args)
    Is run overloaded? Is this a Sublime Text 2 versus 3 thing? Without seeing the examples (point #1) I’m not sure what the current preferred call is for this.

  3. Another tutorial site speaks of creating menu bar additions for the commands rather than having to type into the console. I understand the JSON file format for these additions; it’s pretty straightforward. However a vital component was left out – where does this file go, how is it named? I assume it’s something that’s in the plugin project directory but how to structure this wasn’t explained.

Hopefully that’s enough to get started for now. Thankful for any comments on this and how to get rolling with this.

0 Likes

#2

Welcome to the wonderful world of Sublime Plugin development!

sublime-package files are just zip files with their extensions changed. If you’re using a command line tool you can just provide the sublime-package directly to e.g. the unzip command to see the list of files and extract them; if you’re using a GUI type tool you may need to rename the file to get it to be recognized:

tmartin:dart:~/local/sublime_text_3/Packages> unzip -l Default.sublime-package | head -10
Archive:  Default.sublime-package
  Length      Date    Time    Name
---------  ---------- -----   ----
      141  01-26-2016 11:19   Widget Context.sublime-menu
     1382  06-22-2016 14:24   mark.py
     2402  06-22-2016 14:24   delete_word.py
     4274  06-22-2016 14:24   sort.py
      450  06-22-2016 14:24   duplicate_line.py
      370  01-26-2016 11:19   Line Endings.sublime-menu
       47  01-26-2016 11:19   Preferences (Windows).sublime-settings

Looking at those files you can see some of the default functionality and how it’s implemented, which is a great resource for a working example. Note however that not all of the default functionality is contained in the package; some things are directly in the Sublime Text core for performance reasons, so you won’t find them in the Default package.

Can you show an example of something using run(self, view, args)?

Python doesn’t support overloading in the way you may be familiar with it (i.e. you can’t have several run methods with different argument lists). However you are allowed to define the method as taking extra arguments after the ones that Sublime expects, but you have to provide them at the time you call the method.

By way of example:

class ExampleOneCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        self.view.insert(edit, 0, "Hello, World!")

class ExampleTwoCommand(sublime_plugin.TextCommand):
    def run(self, edit, text):
        self.view.insert(edit, 0, text)

class ExampleThreeCommand(sublime_plugin.TextCommand):
    def run(self, edit, text="Hello, World"):
        self.view.insert(edit, 0, text)

The first of these makes a command that accepts no additional arguments and inserts hard coded text into the start of the current buffer. If you provide any extra arguments, you’ll get an error.

The second makes a command that requires an additional argument named text to give it the text. In this case if you run the command with no arguments you get an error because it’s expecting an argument you’re not giving it. So you would need to use something like view.run_command("example_two", {"text": "Hello, World!"}) to run the command and tell Sublime what the text argument should be.

The third is a blend of the first two; it takes an argument, but it has a value that it will use by default if you don’t provide one.

If you haven’t read through it yet, I recommend a perusal of the Unofficial Documentation which covers a lot of this sort of thing.

Generally speaking, the name of the file is the most important. The file has to be named Main.sublime-menu in order to appear in the main menu, Context.sublime-menu to appear in the context menu, and so on. The unofficial documentation has a list of the various names.

As to the location, that depends on whether or not you’re creating a package for others to use or just for yourself. If you’re just modifying the menu for your own purposes, you would put it into your User package directory; otherwise it goes in the directory for the package that you’re creating (e.g. MyPackage).

4 Likes

#3

Thank you for the information. Knowing about the zip file thing should make extracting those pretty straightforward. As for the python run method call, I’ll have to dig up what I was reading at the time. I got started on the plugin research on Monday, but then actual design work popped up and I haven’t been able to get back to tearing this apart. It very well could be a difference between ST2 and ST3 potentially. Not everything seems to mark which version of the editor it’s relevant to.

0 Likes

#4

The signature of your command’s run() function depends on its purpose. There are a couple of different Classes you can build Commands from based on the scope you need. You can see the definitions of the different types of Command class in the sublime_plugin.py file in Sublime’s application directory.

Basically, you can provide any arguments you want to a command’s run() method, and there’s only one “required” argument: TextCommands expect an edit object as their first argument, which is used by Sublime to track changes for undo/redo/etc. Sublime handles this for you, but the object is provided to the run method in case you need to call “destructive” methods on a View, like insert or replace.

Looking at the Default package’s menu files, the commands they call and the arguments passed through them is pretty instructive. Check out side_bar.py and Side Bar.sublime-menu to see how writing commands that work with project paths is handled, for example.

0 Likes

#5

Many thanks! I have managed to decompose the Defaults package and am poking through looking for examples to cannibalize and learn from.

I did get a command to print my very first version number to the console, so that’s a baby step :wink:

Also diving into snippets as I think a large portion of what I’m looking to do might be encompassed in that feature, if I can sort out a few things first. I’m not entirely sure the snippet will be extensible enough but it might do the trick.

0 Likes