5. Commands
Commands are found throughout Sublime Text. Almost all actions are carried out by Commands. In essence, Commands are the bread-and-butter of getting things done within Sublime Text.
Commands are connected to:
Command Palette items (provided via
.sublime-commandsfiles)Run by selecting Menu items:
from the existing Main Menu and a variety of context menus,
custom menu items can be supplied via
.sublime-menufiles. (See Menus for details.)
Run directly from a Plugin or via the Console Panel:
sublime.run_command('<command_name>', {args})to run an ApplicationCommand,window.run_command('<command_name>', {args})to run a WindowCommand,view.run_command('<command_name>', {args})to run a TextCommand.
(If you attempt to run a TextCommand from one of the other methods [
sublime.run_command()orwindow.run_command(), nothing happens. The same is true for the other methods.)
You can see (and execute) most of the publicly-accessible Commands via the Command Palette: (normally Ctrl-Shift-P).
You can also create your own commands using Plugins.
See also https://docs.sublimetext.io/reference/commands.html .
5.1. Adding Existing Commands to Command Palette
When a Package implements new Commands that should also be available in the Command
Palette, they are added to it using a .sublime-commands file.
5.1.1. Variables Available in .sublime-commands Args
Some commands take paths as parameters. Among these, some commands
(e.g. open_file) support variables passed in strings like
${packages}/PackageName/path/to/file.ext, and snippet-like syntax using “$0” to
mark where to place the cursor, in a “contents” parameter which can be used when
the file may not exist yet.
Contrary to what you might guess, these Commands are not, in fact, preprocessed by Sublime Text before passing them on to the Command, but are processed by the Command itself, in the strings exactly as you passed them. So if you want to create a Command that can take variables, you will need to code the variable substitution yourself, or pass them on to something that does.
Here is an example of how such variables are handled from within the edit_settings
Command (from the EditSettingsCommand class in settings.py from the shipped
Package Default.sublime-package). The comments were inserted for enhanced
readability.
platform_name = {
'osx': 'OSX',
'windows': 'Windows',
'linux': 'Linux',
}[sublime.platform()]
variables = {
'packages': '${packages}',
'platform': platform_name,
}
# -----------------------------------------------------------------
# Prep
# -----------------------------------------------------------------
base_file = sublime.expand_variables(base_file.replace('\\', '\\\\'), variables)
if user_file is not None:
user_file = sublime.expand_variables(user_file.replace('\\', '\\\\'), variables)
# -----------------------------------------------------------------
# Handle '${packages}' variable.
# -----------------------------------------------------------------
base_path = base_file.replace('${packages}', 'res://Packages')
is_resource = base_path.startswith('res://')
file_name = os.path.basename(base_file)
# . . .
# -----------------------------------------------------------------
# Translate 'Default ($platform).sublime-xxxxx' file names
# sometimes found in *.sublime-commands files.
# -----------------------------------------------------------------
if user_file is None:
user_package_path = os.path.join(sublime.packages_path(), 'User')
user_file = os.path.join(user_package_path, file_name)
# If the user path does not exist, and it is a supported
# platform-variant file path, then try and non-platform-variant
# file path.
if not os.path.exists(os.path.join(user_package_path, file_name)):
for suffix in {'.sublime-keymap', '.sublime-mousemap', '.sublime-menu'}:
platform_suffix = ' (%s)%s' % (platform_name, suffix)
if not file_name.endswith(platform_suffix):
continue
non_platform_file_name = file_name[:-len(platform_suffix)] + suffix
non_platform_path = os.path.join(user_package_path, non_platform_file_name)
if os.path.exists(non_platform_path):
user_file = non_platform_path
break
This is the API documentation for the sublime.expand_variables() function:
def expand_variables(value: Value, variables: dict[str, str]) -> Value:
"""
Expands any variables in ``value`` using the variables defined in the
dictionary ``variables``. value may also be a list or dict, in which case the
structure will be recursively expanded. Strings should use snippet syntax,
for example: ``expand_variables("Hello, ${name}", {"name": "Foo"})``.
"""
return sublime_api.expand_variables(value, variables)
Examples:
uses the edit_settings command.
{
"caption": "Preferences: Settings",
"command": "edit_settings",
"args":
{
"base_file": "${packages}/Default/Preferences.sublime-settings",
"default": "// Settings in here override those in \"Default/Preferences.sublime-settings\",\n// and are overridden in turn by syntax-specific settings.\n{\n\t$0\n}\n"
}
},
When command-logging via sublime.log_commands(True) is turned on in the Console,
and Preferences: Settings is executed via the Command Palette, it results in the
following logged in the Console before opening the read-only version from with
Sublime Text’s shipped Default Package. (This was when the new Settings
window had not already been opened previously.)
command: edit_settings {
"base_file": "${packages}/Default/Preferences.sublime-settings",
"default": "// Settings in here override those in \"Default/Preferences.sublime-settings\",\n// and are overridden in turn by syntax-specific settings.\n{\n\t$0\n}\n"
}
command: new_window
command: set_layout {
"cells": [[0, 0, 1, 1], [1, 0, 2, 1]], "cols": [0.0, 0.5, 1.0], "rows": [0.0, 1.0]
}
command: open_file {
"file": "${packages}/Default/Preferences.sublime-settings"
}
command: open_file {
"contents": "// Settings in here override those in \"Default/Preferences.sublime-settings\",\n// and are overridden in turn by syntax-specific settings.\n{\n\t$0\n}\n",
"file": "C:\\Users\\Vic\\AppData\\Roaming\\Sublime Text\\Packages\\User\\Preferences.sublime-settings"
}
Unable to open /C/Users/Vic/AppData/Roaming/Sublime Text/Packages/Default/Preferences.sublime-settings
command: exec {"update_annotations_only": true}
command: exec {"update_annotations_only": true}
So it can be seen that the edit_settings command uses the open_file command
internally.
Note also the function of the $0 variable in the “default” element. It marks
where the cursor will be placed after the text is inserted, in the case where the
file does not already exist. This happens when the user has not created any custom
settings, there is no
<data_path>/Packages/User/Preferences.sublime-settings file yet so
Sublime Text creates one (without saving it yet) and inserts this as its
contents:
// Settings in here override those in "Default/Preferences.sublime-settings",
// and are overridden in turn by syntax-specific settings.
{
| <-- cursor is placed here
}
This file does not get written to disk until the user saves it.
This is found in Context.sublime-menu (context menu within an open file), creating
the “Open Containing Folder…” option:
{ "command": "open_dir", "args": {"dir": "$file_path", "file": "$file_name"}, "caption": "Open Containing Folder…" },
passing the above strings into the “dir” and “file” arguments. It causes the OS’s File Explorer to open and focus placed upon the target file. Nice touch.
The following is from Main.sublime-menu in the Preferences menu:
{
"command": "edit_settings", "args":
{
"base_file": "${packages}/Default/Default ($platform).sublime-keymap",
"default": "[\n\t$0\n]\n"
},
"caption": "Key Bindings"
},
{
"command": "edit_settings", "args":
{
"base_file": "${packages}/Default/Default ($platform).sublime-mousemap",
"default": "[\n\t$0\n]\n"
},
"caption": "Mouse Bindings"
},
It is clear that these are used in a variety of ways: ${packages} and
bare $platform, both inside a string.
5.1.2. Paths
Commands expect forward-slash directory separators in paths if not otherwise noted,
including on Windows (for example,
/C/Program Files/Sublime Text/Lib/python314/sublime_plugin.py).
Relative paths in arguments to commands are assumed to start at the <data_path> directory.
5.2. Further Reading
A relatively-complete list of commands exists in the Unofficial Documentation Commands Page.