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.

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.
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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.