Sublime Forum

Build System only marked text

#1

Hello,

I want to run a shell script called translate-shell with Sublime Text build system. Is there a chance that only can append the marked text to shell command?

The command at end

trans :fr "This is the text"

So I find not a solution for only marked text append in the build system:

{
    "cmd": ["/home/sisi/.bin/scripts/trans", ":fr", "file:///$file"]
}

$File will not work

e[1me[33m[ERROR] File not found: e[0me[22m
[Finished in 0.5s]

Thank you for help if a solution is possible.

Silvio

0 Likes

#2

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.

5 Likes

Execute programs with parameters from text line?
#3

how to translate all selected text with this shell in Sublime?

0 Likes

#4

How one would do that depends on the sorts of files you’re editing and what you expect the results to be (for example, should it try to replace text inline, generate a new file, etc).

0 Likes