Summary

I demonstrate pipify, a script to ‘pipify’ your TUI editors.

Demo

Source

pipify

source
http://github.com/semiosis/pen.el/blob/master/scripts/pen-pipify
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#!/bin/bash
export TTY

stdin_exists() {
    ! [ -t 0 ] && \
        ! test "$(readlink /proc/$$/fd/0)" = /dev/null && \
        ! test "$(readlink /proc/$$/fd/0)" = "$(readlink /proc/$$/fd/1)"
    # stdin may be redirected to the tty, but  will continue to say false (due to a bash bug)
    # So test to make sure 0 does not point to 1
}

stdin_exists && has_stdin=y

tempfile="$(0</dev/null mktemp amp-stdin-$USER.XXXXXXX --tmpdir)"

# Collect the stdin
if test "$has_stdin" = y; then
    cat > "$tempfile"
fi

# save the file descriptors -- these may point to file paths rather than the tty
exec 3>&0
exec 4>&1
exec 5>&2

# Assume stderr has not been redirected and still points to the tty

# # Find the current tty and assign input to it, so we can collect input from the user
# : ${TTY:="$(tm-tty)"}
# exec <"$TTY"

# If it soaked input then return control to the tty
if test "$has_stdin" = y; then
    exec <&2
fi

# Ensure that everything is pointing to the tty
exec 1>&2
exec 2>&2

# We then run our command which has full tty access. It could be amp for example
"$@" "$tempfile"

# Restore stdout and stderr to their regular output file descriptors
# Whatever they used to point to
exec 1>&4
exec 2>&5

# If there was stdin then cat it out to the terminal
# The pipeline around amp is then completed
if test -f "$tempfile"; then
    cat "$tempfile"
fi

Example

Pipify amp, a vi-like TUI editor

Resultant script: aipe

1
2
#!/bin/bash
pipify amp "$@"

Usage:

1
2
# Send hi into amp
echo hi | aipe
1
2
# Send hi into amp and when done editing, write the buffer to stdout
echo hi | aipe | cat
1
echo hi | aipe | vim -

As you can see, I was able to edit the stdin in amp, and then pass the stdout of amp to vim.