3
votes

I have an external command line program that I would like to invoke from elisp. This is easy enough with shell-command, but it doesn't work correctly when the command line program is interactive, which in my particular case it is: The invoked script sees EOF when it reads stdin when I call it like this:

  ;; upload command is a string with the name of
  ;; a python script and some args
  (shell-command upload-command
                 (get-buffer-create "*upload output*")))))

The python script identified by upload-command may ask some yes/no questions and it may prompt for a password, for which I'd like masked input. Ideally, all of this interaction would occur within the minibuffer.

How can I arrange things so that my external interactive command interacts with the user via minibuffer when called via elisp?

1

1 Answers

6
votes

The easiest way is to use either make-comint or make-comint-in-buffer:

(make-comint-in-buffer "upload-script-process" "*upload output*" upload-command)

This will runs the script in a buffer like a shell buffer, so it doesn't fulfill the requirement of having all interaction happen in the minibuffer. It will, however, automatically read passwords in masked form from the minibuffer, provided the password prompt matches comint-password-prompt-regexp.

Note that upload-command in this example here needs to be the name of an executable file on exec-path. Any extra switches or other arguments to the script have to be passed as string arguments to make-comint:

(make-comint-in-buffer "upload-script-process" "*upload output*" 
   upload-command nil "--verbose" "--other-option")

See the Emacs documentation for more details.