--- /dev/null
+Copyright (c) 2014 moshee
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--- /dev/null
+# pipe
+
+Select text to pipe into external commands and replace it with the output. Sort
+of like `!` in vim. Commands are sent to your `$SHELL`.
+
+Default keybinding to activate is `cmd-;`.
+
+![pipe in action](https://i.ktkr.us/hoeJ)
--- /dev/null
+# Keybindings require three things to be fully defined: A selector that is
+# matched against the focused element, the keystroke and the command to
+# execute.
+#
+# Below is a basic keybinding which registers on all platforms by applying to
+# the root workspace element.
+
+# For more detailed documentation see
+# https://atom.io/docs/latest/advanced/keymaps
+'.editor':
+ 'cmd-;': 'pipe:run'
--- /dev/null
+{View, EditorView} = require 'atom'
+
+module.exports =
+class CommandView extends View
+ @placeholders: [
+ 'sort -n'
+ 'tac'
+ 'sed \'s/^/\\/\\//g\''
+ 'grep foo'
+ 'tee ~/temp.txt'
+ ]
+
+ @content: ->
+ @div class: 'pipe-command', =>
+ @subview 'commandLine', new EditorView(
+ mini: true
+ placeholderText: @samplePlaceholder()
+ )
+
+ @samplePlaceholder: ->
+ @placeholders[Math.floor(Math.random()*@placeholders.length)]
+
+ initialize: (callback) ->
+ @on 'core:cancel core:close', =>
+ callback(null)
+ @detach()
+ @on 'core:confirm', =>
+ callback(@commandLine.getText())
+ @detach()
+
+ atom.workspaceView.append(this)
+ @commandLine.focus()
--- /dev/null
+{Range} = require 'atom'
+{spawn} = require 'child_process'
+CommandView = require './command-view'
+
+module.exports =
+ activate: ->
+ atom.workspaceView.command 'pipe:run', => @run()
+
+ run: ->
+ editor = atom.workspace.getActiveEditor()
+ view = atom.workspaceView.getActiveView()
+ return if not editor?
+
+ new CommandView (commandString) ->
+ if not commandString
+ view.focus()
+ return
+
+ range = editor.getSelectedBufferRange()
+ stdout = ''
+ stderr = ''
+
+ proc = spawn process.env.SHELL, ["-l", "-c", commandString]
+
+ proc.stdout.on 'data', (text) ->
+ stdout += text
+
+ proc.stderr.on 'data', (text) ->
+ stderr += text
+
+ proc.on 'close', (code) ->
+ text = stderr || stdout
+ if not text then return
+
+ if text.slice(-1) is '\n'
+ text = text.slice(0, -1)
+
+ editor.setTextInBufferRange(range, text)
+ editor.setSelectedBufferRange(new Range(range.start, range.start))
+ view.focus()
+
+ proc.stdin.write(editor.getSelectedText())
+ proc.stdin.end()
--- /dev/null
+{
+ "name": "pipe",
+ "main": "./lib/pipe",
+ "version": "0.0.0",
+ "description": "Pipe text in and out of external commands.",
+ "activationEvents": ["pipe:run"],
+ "repository": "https://github.com/moshee/atom-pipe",
+ "license": "MIT",
+ "engines": {
+ "atom": ">0.72.0"
+ },
+ "dependencies": {
+ }
+}
--- /dev/null
+// The ui-variables file is provided by base themes provided by Atom.
+//
+// See https://github.com/atom/atom-dark-ui/blob/master/stylesheets/ui-variables.less
+// for a full listing of what's available.
+@import "ui-variables";
+
+.pipe-command {
+ padding: 1px;
+}