Filter text through shell command


#1

I like the ability of VIM to pipe text to shell commands and replace the text with the output of the shell command.

Example:

In VIM:

  1. In Normal mode, type “:” to enter commandline mode.
  2. In commandline mode, type “%!sort”

This will pipe all lines through the sort program and the entire buffer will be replaced with the output of the sort command. Is there a way to do this?


Announce: shell-it
#2

I don’t know of any way, but that sounds useful. I’ll create a package for this now.


#3

I was thinking a menu item called “pipe selected text through shell command and replace with its output” (when text is selected), or “pipe all text through shell command and replace with its output” (if no text is selected). Of course the wording must be more concise; I’m just trying to show you what I’m thinking.

When the menu item is chosen, a dialog box pops up where you type in your shell command. Then buttons “run” or “cancel” would be at the bottom.

But this really needs to be thought through. VIM supports all kinds of shell command use. Which features will the new package support?

Here are a couple of use cases:

You can pipe only the selected text through the shell command. VIM example: sort only a subset of the file via first using visual mode to select text, then typing “:!sort” (don’t type the “%” character as in the example above)

You can also just run a shell command and insert its output at the cursor (there is no text piped into the shell command). VIM example “:r!ls” Inserts the current directory listing into the document at the cursor


#4

How is this going to work on Windows?


#5

Right now I’m just releasing a package that runs the text buffer into the stdin of a node child process and then replace the buffer with stdout. I’ll put in a long timeout like a minute.

Then we can see what we need to improve it.

It should work the same since node processes work on windows.

Edit: I’ll only use the selected text so you can select-all if you want.


#6

I’ve released shell-it 0.1.0. Try it out.

It has no readme yet. I’ll do that now.

Meanwhile:

  • select text
  • hit shift-ctrl-alt-S to execute shell-it:open
  • type in cmd ( tested with ls and wc)
  • hit enter

I don’t think it’s too bad for 2 hrs work.


#7

Sorry, I must be missing something.

My question is:
How are Unix shell programs (such as sort/ls/etc.) are going to work on Windows?

I don’t have much experience with Windows shell, does it support piping, etc?


#8

I’m pretty sure it does. The commands would be different though. Test it with dir which I think is the windows version of ls. It should print a directory listing.


#9

Cool then. I am not on Windows, just wanted to make sure its gonna be a cross platform solution.


#10

Pretty awesome! One issue: after I run the command successfully, the focus seems to be outside the text editor window. Not exactly sure where it is, but I can’t type letters into the buffer, nor can I use the arrow keys to navigate the document. Pressing “tab” highlights some items in the status bar at the bottom of the screen.

Please ensure the focus (and cursor) is left in a sane place after the command has executed. A the end of the inserted text could work, but at the start could also work.

Ideally you would just leave the entire inserted text selected (as it is now in the current version). But focus should remain in the editor, that’s really the main issue.


#11

Yeah, I noticed that. It’s a pain to have to click on the editor.

I’ll fix that today. I’m also adding a feature where the stdin/stdout can optionally go to/from the clipboard. I ran into this need when I wanted to do a wc without clobbering the text.


#12

This is awesome, @mark_hahn. I’ve been wanting something like this for a while. :clap:

I’m also adding a feature where the stdin/stdout can optionally go to/from the clipboard. I ran into this need when I wanted to do a wc without clobbering the text.

Sweet!

In case it helps, TextMate’s “Filter Through Command” UI may offer inspiration for additional modes of operation.


#13

I just released the fix.


#14

I think all the cases you mention can already be handled by proper choice of selection.


#15

Neat. I’m really amazed at how fast this feature went from suggestion to the end user being able to use it… Neatest software experience I’ve had in years! … Less than 24 hour turn-around!


#16

I was hoping to keep the UI trivial but it’s always tempting to let elegance creep in. Textmate seems to have overdone it, IMHO.

If anyone finds anything needed to be impossible let me know.


#17

Mostly they won’t, because Windows has a different shell and set of command-line programs. The whole point of this package is to run programs outside of Atom. If the program doesn’t exist you’re out of luck. You should be able to use Windows commands however.

If you want Unix commands in a Windows environment, you should try installing Cygwin. It does a wonderful job of porting them to Windows, including the bash shell.


#18

The last time I used windows I found a collection of normal windows exe commands that implemented most of the bash primitives, like ls, echo, etc. I was able to switch between windows shell and bash pretty easily. Cygwin is a bloated solution that isn’t native to the windows world.

I don’t remember exactly what command set I used but a quick google gave me win-bash and getgnuwin32.

Edit: I should add that all this is IMHO.


#19

Fyi:

I’ve released 0.2.0 which is a somewhat major rewrite. I’m done adding features for now.

  • Added clipboard options
  • Working directory now set to project containing file
  • On exception stderr is shown in popup
  • Return works everywhere
  • Escape closes dialog

#20

Very useful package. I know you try to keep it lean and clean, but one feature might be worth considering: run the exact same command one more time.

This would be useful for inserting UUIDs in my case, but it sure has more use cases, like selecting a different input and filtering that.

The key combination might be shift-ctrl-alt-cmd-S.

What do you think?