It looks like there are probably at least a couple of packages that already do this, based on this search on packagecontrol.io. You’re probably better off using one of those and/or creating a PR on the existing package if it doesn’t meet your needs than you are trying to recreate something similar.
That said, for reference here is a simple example of a command named shell
that does this. This is for illustration only, it’s missing a lot of parts that would make it more robust, such as error handling and not blocking Sublime while the external command is running, among other things. Still, it should give you an idea on how you would capture the text out of the file, run it through a command, and replace it with the output.
import sublime
import sublime_plugin
import subprocess
class ShellCommand(sublime_plugin.TextCommand):
def run(self, edit, cmd=None):
if cmd is None:
return self.view.window().show_input_panel("Command:", "sort -n",
lambda cmd: self.view.run_command("shell", {"cmd": cmd}),
None, None)
for region in self.get_selected_regions():
text = self.view.substr(region)
result = self.run_shell_command(cmd, text)
if result is not None:
self.view.replace(edit, region, result)
def run_shell_command(self, command, input_text):
proc = subprocess.Popen(command,
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
try:
stdout, stderr = proc.communicate(input_text.encode("utf-8"), 5)
if proc.returncode == 0:
return stdout.decode("utf-8")
except:
proc.kill()
return None
def get_selected_regions(self):
result = [region for region in self.view.sel() if not region.empty()]
if not result:
result = [sublime.Region(0, self.view.size())]
return reversed(result)