I'm new in Python and Sublime API. I'm trying to write a simple plugin for ST3, which should close an empty pane (when I press Ctrl-E). Here are the steps which I'm trying to implement:
And there is the code I'm trying to write. Yes, there are a lot of error, obviously.
import sublime_plugin
class CloseEmptyPane(sublime_plugin.WindowCommand):
def run(self):
window = self.window
if window.num_groups() = 1:
return
active_pane = window.active_group()
tabs_in_pane = window.views_in_group(active_pane)
current_tab = active_view_in_group(active_pane)
if tabs_in_pane > 0:
current_tab.run_command("close_file")
else:
active_pane.run_command("close_pane")
I maybe wrong, but it seems the main problem occurs when I'm trying to check the number of open tabs in current pane. How it may be fixed?
Your first attempt is a pretty good start for what you're trying to do, you just have a couple of minor syntax issues and a couple of problems having to do with how the API works.
An adjusted version of your code is below to get you rolling.
import sublime_plugin
# Note 1: Add "Command" to name
class CloseEmptyPaneCommand(sublime_plugin.WindowCommand):
def run(self):
window = self.window
# Note 2: '=' is assignment; use '==' for equality
if window.num_groups() == 1:
return
active_pane = window.active_group()
# Note 3: views_in_group returns a list of views
tabs_in_pane = len(window.views_in_group(active_pane))
# Note 4: This method is in window
current_tab = window.active_view_in_group(active_pane)
# Note 5: These commands are window commands
if tabs_in_pane > 0:
window.run_command("close_file")
else:
window.run_command("close_pane")
Although not technically needed, it is good practice to suffix classes that implement commands with Command
; Sublime throws that part away when creating the internal command name, but it makes your code easier to read for other plugin authors (and yourself) as more complicated plugins may have other non-command classes in them.
In the API documentation, anything that lists its return in [square brackets]
is telling you that the return value is a list of things (i.e. an array). So your problem with getting the number of tabs in the group is that the method you're calling tells you what all of the views are, instead of how many of them there are. Here the python len
function can get the length of the list for you.
The big gotcha (that catches everyone out at some point) is that View
, Window
and the sublime
module all have a run_command
method to run a command, but the commands they can execute are slightly different.
View.run_command
can run commands implemented as a TextCommand
(things that modify the buffer), while Window.run_command
can run a TextCommand
or a WindowCommand
. In this case the commands you're trying to use are WindowCommand
commands, so for them to work you need to tell the window to run them, not the current view.
It can be handy when you're working on a plugin to keep the Sublime console open so that you can see what's happening. That'll tell you right away about syntax problems in your code (like the =
vs ==
issue) when you save, and will give you an error when you try to invoke something that doesn't exist (like active_view_in_group
if you don't tell it that you're running it on the window
).
Where that falls down is that run_command
doesn't generate an error if you try to run a command that it doesn't know how to handle; in fact it doesn't even generate an error if you try to run a command that doesn't exist.
For that sort of problem you just have to note that if there are no other errors and you're sure it's getting to that part of the plugin, you may be using the wrong thing to run the command or it may be spelled wrong.