Running Shell Command Pipelines From Your Text Editor

What? Why!?

Modern text editors provide lots of commands for manipulating text. Unix shell pipelines also combine into text manipulation utilities, and of course both overlap sometimes. Sorting lines of text is a common first-class command in both environments.

My own approach to editing text changed through using aoeui (asdfg really), a terminal-based editor that eschews many builtin commands in of favor supporting the use of shell pipelines and does so without offering a special mechanism for entering these.

Quoting the documentation:

^E brings all the power of UNIX text processing commands into your editing session, including your own programs and scripts. This is the best way to customize your editor. ^E executes the shell command pipeline that is the current selection, using the content of the clip buffer as its standard input. The selection is replaced with the command's standard output.

Ever since then I've relied on this feature in every editor I've used, Shell command pipelines are a and flexible editor-independent toolkit that let us replicate many builtin or missing features, and I'm comfortable assembling them.

This document collects ways to run arbitrary shell command pipelines in different text editors.

The main point of differentiation between them is whether we enter the commands in the same text area as the text they operate on. The advantage in using the same area for both is that we can use the same mechanisms to operate on both, and prepare commands independently of when we want to run them. Using a different area on the other hand lets the editor provide additional mechanisms for writing the commands, like completion or an interactive history, and leaves the main text area to care about a single consistent document without arbitrary shell commands in it.

Some good hints about writing unix tools that are always good to reference: Hints for writing Unix tools

Editors

Acme

Acme supports shell commands by selecting them with mouse button 2. To work as a pipeline they must be prefixed with |. Commands can be entered anywhere, it's all text.

If you are unfamiliar with acme I recommend Russ Cox's tour of it.

Aoeui

...and asdfg

Aoeui supports shell pipelines with the keyboard shortcut Control-E while asfdg uses Control-R. Commands are entered in the main text area.

Emacsen

All emacsen I have used, like GNU Emacs or OpenBSD Mg, support shell pipelines through shell-command-on-region, which is often bound to Meta-|. Commands are entered in the minibuffer.

Gedit

Gedit supports shell pipelines with the help of the "External Tools" plugin. Enable the plugin, then in "Manage External Tools…" create a tool with a script like

#!/bin/sh
cmd="$(cat)"
wl-paste | sh -c "$cmd"

Set input to "Current selection" and output to "Replace current selection".

Done this way commands are entered in the main text area, an alternate version could bypass the clipboard, read stdin from the document and the commands in a separate dialog.

Helix

Helix supports shell pipelines through the pipe command invoked with | in normal mode.

Lite

Lite supports shell pipelines through the Exec: Replace command from the exec plugin. Commands are entered in a command line.

Lite XL probably supports the same plugin.

Micro

Micro supports shell pipelines through textfilter. Commands are entered after the textfilter command on the command line (Ctrl-E), and we may want to bind a key to "command-edit:textfilter ".

Nano

Nano supports shell pipelines through execute (Control-T). Commands are entered in a command line and must be prefixed with | to work as a pipeline, which we can enter ourselves or toggle with flippipe (Meta-|).

Sam

Sam supports shell commands through the | command. Commands are entered in the command window.

TextMate

TextMate was the first editor I built support for this for, but unless I find a backup of that it's now lost to time. The script was essentially the same as the one for gedit though.

Vi

Vi and its descendants like vim or nvi support shell pipelines through the ex command :!. Commands are entered in the ex command line.

Visual Studio Code

VSCode supports shell pipelines with the Edit with Shell Command extension and its EditWithShell: Run command command. Commands are entered in a command line or selected from history.