2

How do I read the entire contents of stdin into an Emacs buffer in #! /usr/bin/env emacs --script mode? Stdin may not be a regular file.

Lassi
  • 377
  • 1
  • 7
  • See also: https://superuser.com/questions/31404/how-to-make-emacs-read-buffer-from-stdin-on-start – Lassi Nov 28 '19 at 18:52

2 Answers2

1

After a bit of research, apparently this is the best we can do right now:

#! /usr/bin/env emacs --script

(defun slurp-stdin ()
  (condition-case nil (while t (insert (read-from-minibuffer "") "\n"))
    (error)))

(with-temp-buffer
  (slurp-stdin)
  (princ (buffer-string)))
  • It abuses a gimmick of read-from-minibuffer that causes that function to read a line from stdin when Emacs is in batch mode.
  • There's no fundamental reason to read a line at a time instead of chunk-at-a-time, but I can't find a chunk-at-a-time read function in Emacs.
  • It cannot distinguish between different kinds of newlines (CR or CR/LF) and cannot differentiate between the presence or lack of a final newline at the end of stdin. I'm not sure what kind of newline conversion (if any) is done.
  • It cannot distinguish between end-of-file and other errors. Emacs has an end-of-file condition type that is used for that purpose by read, but read-from-minibuffer does not use it.
  • On the bright side, it works fine with pipes and sockets.
Lassi
  • 377
  • 1
  • 7
1

Read /dev/stdin, e.g.,

$ date -u | emacs --batch --eval '(insert-file-contents "/dev/stdin")' --eval '(princ (buffer-string))'
Thu Nov 28 19:12:02 UTC 2019

Not sure about Windows though.

xuchunyang
  • 14,302
  • 1
  • 18
  • 39