[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: How to interact with a shell-like process behind the scenes?
From: |
Ship Mints |
Subject: |
Re: How to interact with a shell-like process behind the scenes? |
Date: |
Wed, 21 May 2025 07:10:07 -0400 |
On Tue, May 20, 2025 at 11:42 PM <mbork@mbork.pl> wrote:
> Hi all,
>
> I have a program which displays a prompt on stdout, accepts a line of
> input, does something with it, displays the results (possibly in many
> lines, in a known format, e.g. JSON), and shows the prompt again.
> I need Emacs to be able to interact with it, as in: send the said line
> of input and receive the said output. I don't want the /user/ to do
> that, that is, I don't need it to be interactive in any way -- just that
> some Elisp function can "wrap" the process, as in, accept the input,
> send it to the process, and receive the output, most probably via
> a callback. How do I do that?
>
> I read about `make-process' and `start-process', but I am a bot worried
> about making it robust. What if the external process gets killed, for
> example? I probably should detect it and start it anew, etc. I have
> a feeling that it's probable that Emacs already has something which
> could help me.
>
> I'm reading now about Comint mode. From what I see, it's not
> necessarily what I want, because I don't really need an interactive,
> REPL-like thing, but something working in the background.
>
> On the other hand, I asked an Internet parrot, and it suggested Comint
> mode with the following (obviously wrong) snippet:
>
> --8<---------------cut here---------------start------------->8---
> (require 'comint)
>
> (defun my/send-to-repl (input callback)
> (let* ((buffer-name "*my-repl*")
> (proc-name "my-repl")
> (command '("my-repl-binary" "--some-arg"))
> (proc (get-buffer-process buffer-name)))
> (unless (and proc (process-live-p proc))
> (setq proc
> (make-comint-in-buffer proc-name buffer-name
> (car command) nil
> (cdr command))))
> (with-current-buffer buffer-name
> (let ((start (point-max)))
> (goto-char start)
> (insert input)
> (comint-send-input)
> (set-process-filter
> proc
> (lambda (proc output)
> ;; Accumulate and call callback when prompt is detected
> (with-current-buffer (process-buffer proc)
> (insert output)
> (when (string-match "my-repl-prompt>" output)
> (let ((response (buffer-substring start (point-max))))
> (funcall callback response)))))))))
> --8<---------------cut here---------------end--------------->8---
>
> It's wrong because it assigns the output of `make-comint-in-buffer' to
> `proc', while the Elisp manual says that that function returns the
> /buffer/. Another Internet parrot produced another code which starts
> with defining a minor mode - again, from what I understand, this doesn't
> make much sense, since I don't really need anything but the Fundamental
> mode (the buffer won't be used for user interaction and can even be
> a hidden one).
>
> So, should I use Comint mode for that or something else? If so, where
> can I find examples of code using it? From what I grepped in the Emacs
> sources, most if not all cases where Comint mode is used are for
> interactive sessions.
>
> Thanks in advance,
>
Here's someone else addressing something similar
https://github.com/milanglacier/termint.el
Re: How to interact with a shell-like process behind the scenes?, mbork, 2025/05/22
Re: How to interact with a shell-like process behind the scenes?,
Ship Mints <=
Re: How to interact with a shell-like process behind the scenes?, Eduardo Ochs, 2025/05/22