Standard build systems in Sublime don’t support any sort of variable that expands out to the currently selected text, since in the general case you want to build files and not just selected parts of them.
When you execute a build, the sublime-build
file can contain the optional key target
that specifies what Sublime command to use to execute the build, and if that key is not used, it’s assumed to be the built in exec
command.
In order to do what you want, you need to create a custom build target that does what exec
does while also being able to grab the currently selected text and provide it for use in the build system.
An example of that is the following code. To use this, select Tools > Developer > New Plugin...
from the menu, then replace the entire contents of the buffer that opens with the following code, and save it in the default location with a descriptive name like exec_selection.py
:
import sublime
import sublime_plugin
from Default.exec import ExecCommand
class ExecSelectionCommand(ExecCommand):
def run(self, **kwargs):
# Extract from our arguments the potential replacement build options
# that can contain the new $SELECTION variable.
cmd_sel = kwargs.pop("cmd_sel", None)
shell_cmd_sel = kwargs.pop("shell_cmd_sel", None)
# Obtain the selection from the currently active view, which may be an
# empty string.
v = self.window.active_view()
selection = "" if v is None else "\n".join([v.substr(s) for s in v.sel()])
# Obtain the standard variables, then add in the selection if we found
# one. If the selection is empty, it's not added to the list of
# variables so that a default can be used.
cVars = self.window.extract_variables()
if selection:
cVars["SELECTION"] = selection
# If the build has an alternate "cmd" argument, expand it.
if cmd_sel is not None:
kwargs["cmd"] = sublime.expand_variables(cmd_sel, cVars)
# If the build has an alternate "shell_cmd" argument, expand it.
if shell_cmd_sel is not None:
kwargs["shell_cmd"] = sublime.expand_variables(shell_cmd_sel, cVars)
# Let our parent class (the standard exec command) perform the build
# now.
super().run(**kwargs)
This creates a new command named exec_selection
that mimics what the exec
command does, while providing support for a new variable named $SELECTION
that will expand out to the current selection if there is any text selected.
With this in place, you can use a sublime-build
file similar to the following:
{
// Specify our own command to execute the build, providing the correct
// arguments to pass to it to cancel a running build.
"target": "exec_selection",
"cancel": {"kill": true},
"cmd_sel": ["/home/tmartin/trans", "-no-ansi", ":fr", "${SELECTION:No Selection}"]
}
Something important to note here is that when you run a build, Sublime automatically expands the variables in some of the parts of the sublime-build
before it runs the build target, and as a part of this operation any variables that it doesn’t recognized are expanded as empty strings.
The cmd
and shell_cmd
variables are included in this, and so if you try to use $SELECTION
in them directly it will always expand out to be an empty string because the variable is unknown.
To get around that, when using this custom target, use cmd_sel
in place of cmd
or shell_cmd_sel
in place of shell_cmd
; Sublime will leave those two values alone, allowing the custom build target to expand the variables out itself.
Note also that $SELECTION
will expand to the empty string if there is no selection. In the build system above the contruct ${SELECTION:No Selection}
expands out to the currently selected text if there is any, or the text “No Selection” if there is no text selected.