Home » Questions » Computers [ Ask a new question ]

How to make Emacs read buffer from stdin on start?

How to make Emacs read buffer from stdin on start?

With Vim I can easily do

Asked by: Guest | Views: 408
Total answers/comments: 5
bert [Entry]

"Correct, it is impossible to read a buffer from stdin.

The only mention of stdin in the Emacs info pages is this, which says:

In batch mode, Emacs does not display
the text being edited, and the
standard terminal interrupt characters
such as C-z and C-c continue to
have their normal effect. The
functions prin1, princ and print
output to stdout instead of the echo
area, while message and error
messages output to stderr.
Functions that would normally read
from the minibuffer take their input
from stdin instead.

And the read function can read from stdin, but only in batch mode.

So, you can't even work around this by writing custom elisp."
bert [Entry]

"You can redirect to a file, then open the file. e.g.

echo 123 > temp; emacs temp

jweede notes that if you want the temp file to automatically be removed, you can:

echo 123 > temp; emacs temp; rm temp

The Emacsy way to do this is to run the shell command in Emacs.

M-! echo 123 RET

That gives you a buffer named *Shell Command Output* with the results of the command."
bert [Entry]

"Another possibility not mentioned in any of the previous answers is to use /dev/stdin if your chosen Unix variant has it.

Simply trying to open /dev/stdin directly doesn't work, because Emacs does a few checks and then reports Symbolic link that points to nonexistent file. (And if Emacs would have allowed you to load the file, then trying to save it again as /dev/stdin would rarely do what the user expected.)

However combining /dev/stdin with the --insert argument does work:

echo 123 | emacs --insert /dev/stdin

It should be noted that this version only works when using X. If you need a solution which works in a terminal I suggest you look at another answer."
"Another possibility not mentioned in any of the previous answers is to use /dev/stdin if your chosen Unix variant has it.

Simply trying to open /dev/stdin directly doesn't work, because Emacs does a few checks and then reports Symbolic link that points to nonexistent file. (And if Emacs would have allowed you to load the file, then trying to save it again as /dev/stdin would rarely do what the user expected.)

However combining /dev/stdin with the --insert argument does work:

echo 123 | emacs --insert /dev/stdin

It should be noted that this version only works when using X. If you need a solution which works in a terminal I suggest you look at another answer."
bert [Entry]

"It's possible to create a simple shell function which works as it is reading from stdin (although in fact it is writing to a temporary file then reading that). Here's the code I'm using:

# The emacs or emacsclient command to use
function _emacsfun
{
# Replace with `emacs` to not run as server/client
emacsclient -c -n $@
}

# An emacs 'alias' with the ability to read from stdin
function e
{
# If the argument is - then write stdin to a tempfile and open the
# tempfile.
if [[ $# -ge 1 ]] && [[ ""$1"" == - ]]; then
tempfile=""$(mktemp emacs-stdin-$USER.XXXXXXX --tmpdir)""
cat - > ""$tempfile""
_emacsfun --eval ""(find-file \""$tempfile\"")"" \
--eval '(set-visited-file-name nil)' \
--eval '(rename-buffer ""*stdin*"" t))'
else
_emacsfun ""$@""
fi
}

You just use the function as an alias for emacs, e.g.

echo ""hello world"" | e -

or as normal from files

e hello_world.txt

Replacing emacs by emacsclient in the function works as well."
bert [Entry]

"offhand, something like:

$ echo 123 > tmp.txt; emacs tmp.txt

or

$ echo 123 > tmp.txt; emacs tmp.txt; rm tmp.txt

is an option. Emacs just doesn't integrate with UNIX the way vim does."