Home Download Buy Blog Forum Support

Run file contents through external command

Run file contents through external command

Postby nachocab on Mon Aug 08, 2011 11:11 pm

Hello,
I want to take the contents of my current file as input, send it through a series of pipes (using sed and awk to fix mistakes) and replace the contents with the output of the pipes. What's the best way to do this?

Example file:
My apointment is tomorow.

I want to run the command
sed 's/apointment/appointment/' | sed 's/tomorow/tomorrow/'

To get the output
My appointment is tomorrow.
nachocab
 
Posts: 23
Joined: Thu Jul 07, 2011 2:22 pm

Re: Run file contents through external command

Postby aparajita on Tue Aug 09, 2011 5:55 am

You can write a plugin that will, for example, take a command line to execute, send the contents of the current buffer (or current selection) to the command line, and replace the buffer or selection with the output.
aparajita
 
Posts: 177
Joined: Sun Jul 24, 2011 10:42 pm

Re: Run file contents through external command

Postby nachocab on Tue Aug 09, 2011 9:13 am

Does that mean I have to learn Python? In Textmate is was as easy as point and click.
nachocab
 
Posts: 23
Joined: Thu Jul 07, 2011 2:22 pm

Re: Run file contents through external command

Postby nachocab on Tue Aug 09, 2011 11:36 am

So, I'm trying something like this, but I can't get it to work

Code: Select all
import sublime, sublime_plugin
import subprocess

"""
Runs an external command with the selected text,
which will then be replaced by the command output.
"""
class ExternalCommand(sublime_plugin.TextCommand):
    def run(self, edit, args):
        # nothing selected: process the entire file
        region = sublime.Region(0L, self.view.size())
       
        p = subprocess.Popen(
            args,
            shell   = True,
            bufsize = -1,
            stdout  = subprocess.PIPE,
            stderr  = subprocess.PIPE,
            stdin   = subprocess.PIPE)

        output, error = p.communicate(self.view.substr(region).encode('utf-8'))

        if error:
            sublime.errorMessage(error.decode('utf-8'))
        else:
            edit.replace(region, output.decode('utf-8'))
nachocab
 
Posts: 23
Joined: Thu Jul 07, 2011 2:22 pm

Re: Run file contents through external command

Postby aparajita on Wed Aug 10, 2011 8:13 pm

nachocab wrote:So, I'm trying something like this, but I can't get it to work

Code: Select all
            edit.replace(region, output.decode('utf-8'))


You aren't calling replace correctly, it's a View method. There should have been an error message in the console. Try:

Code: Select all
self.view.replace(edit, region, output.decode('utf-8'))
aparajita
 
Posts: 177
Joined: Sun Jul 24, 2011 10:42 pm

Re: Run file contents through external command

Postby nachocab on Sat Aug 13, 2011 1:17 pm

When I do that, sublime crashes and I don't know how to fix it because I can't see the error message. Is there a way to debug this? I'm pretty new at this.
nachocab
 
Posts: 23
Joined: Thu Jul 07, 2011 2:22 pm

Re: Run file contents through external command

Postby shebiki on Mon Oct 10, 2011 12:30 am

I found this post when searching google to find out how to apply a unix command to a selection in sublime and it provided a great start for a solution. Here is a version of the original code that does the job. It'd be great if sublime could have a similar feature built in or this command bundled.

To use it, select some text and then from the console enter "view.run_command('external_filter')", sublime will prompt you for a command, enter a valid unix command and it will pipe your selection through the command and replace the text with it's output.

Code: Select all
import sublime
import sublime_plugin
import subprocess

# view.run_command('external_filter')
class ExternalFilterCommand(sublime_plugin.TextCommand):
  def run(self, edit):
    self.view.window().show_input_panel('Command', '',
      lambda command: self.runCommand(edit, command),
      None, None)

  def runCommand(self, edit, command):
    regions = self.view.sel()
    if len(regions) == 1 and regions[0].empty():
      # No selection use the entire buffer
      regions = [sublime.Region(0, self.view.size())]

    for region in regions:
      self.execCommand(edit, command, region) 

  def execCommand(self, edit, command, region):
    p = subprocess.Popen(command, shell=True, bufsize=-1,
      stdout=subprocess.PIPE, stderr=subprocess.PIPE, stdin=subprocess.PIPE)
    output, error = p.communicate(self.view.substr(region).encode('utf-8'))
    if error:
      sublime.error_message(error.decode('utf-8'))
    else:
      self.view.replace(edit, region, output.decode('utf-8'))
shebiki
 
Posts: 1
Joined: Mon Oct 10, 2011 12:21 am

Re: Run file contents through external command

Postby bedge on Tue Oct 15, 2013 8:42 pm

This just needs to be included in the default distribution.
Select buffer, press hotkey, prompt for command, replace buffer with command output.
bedge
 
Posts: 5
Joined: Tue Apr 23, 2013 4:56 pm


Return to General Discussion

Who is online

Users browsing this forum: Google [Bot], mlf and 32 guests