3

I am trying to execute an external program on a string. This code works, but it saves the string to a temporary file in order to run call-process. This seems quite roundabout. I'd rather not use a shell command either.

Is there a way to call an external program on a string without writing to a temporary file?

(defun my/execute-program-on-string (program string &optional args)
  "Call PROGRAM with ARGS on STRING."
  (let  (input-file input-buffer output-buffer exit-code result)
    (unwind-protect
    (setq input-file (make-temp-file "/tmp/emacs-execute-"))
      (write-region string nil input-file nil)
      (setq input-buffer (create-file-buffer input-file)
        output-buffer (generate-new-buffer (format "*%s*" program))
        exit-code (call-process program input-file output-buffer nil args))
      (if (zerop exit-code)
      (setq result
        (with-current-buffer output-buffer (buffer-string)))
    (throw 'external-program-error exit-code))
      (progn
    (kill-buffer input-buffer)
    (kill-buffer output-buffer)))
    result))


(my/execute-program-on-string "cat" "Hello, World!" "-n")
3
  • My version of Emacs does not have f-write-text ... Your minimal working example requires using undisclosed third-party libraries ... Many other forum participants might be able to help if we didn't have to familiarize ourselves with that library and install it ...
    – lawlist
    Commented Jun 17, 2018 at 2:16
  • @lawlist Good point. I've replaced that function call with an equivalent line for better reproducibility.
    – Hatshepsut
    Commented Jun 17, 2018 at 2:56
  • Does the function buffer-substring, with optional arguments START END help any with this situation? This would turn the buffer contents (or the portion between START/END) into a string without writing it to a file, if that is what is being sought here.
    – lawlist
    Commented Jun 17, 2018 at 4:36

1 Answer 1

4

You can use call-process-region to send string to a program as standard input, for example,

(with-temp-buffer
  (call-process-region "Hello, World!" nil "cat" nil t nil "-n")
  (buffer-string))
;; => "     1   Hello, World!"

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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