Search code examples
emacselispmozrepl

Emacs: what is the conventional way of receiving output from a process?


My aim is to get the output from a process in Emacs.

For example, M-x run-python gives me a python shell *Python* that I can send python code to. If I send print "hello world" to *Python*, I hope Emacs can know the result once the execution is finished and echo it in the mini-buffer.

Is it possible to add something like a callback?


Solution

  • Thanks to the comments from @lawlist , I solved my problem by creating the following filter function and assigning it to the process (*MozRepl* in my case) with (set-process-filter (get-buffer-process "*MozRepl*") 'moz-controller-repl-filter)

    (defun moz-controller-repl-filter (proc string)
      "Filter function of *MozRepl*.
    
    It gets the useful output of *MozRepl*, store it in `moz-controller-repl-output` and `kill-ring`"
      (when (buffer-live-p (process-buffer proc))
        (unless (string= string "repl> ")   ; ignore empty output (page up, page down, etc)
          (setq moz-controller-repl-output
                (replace-regexp-in-string "\"\\(.+\\)\"\nrepl> " "\\1" string))
          (kill-new moz-controller-repl-output) ; append to kill-ring
          (message moz-controller-repl-output) ; show the copied content in echo area
          )
        (with-current-buffer (process-buffer proc)
          (let ((moving (= (point) (process-mark proc))))
            (save-excursion
              ;; Insert the text, advancing the process marker.
              (goto-char (process-mark proc))
              (insert string)
              (set-marker (process-mark proc) (point)))
            (if moving (goto-char (process-mark proc)))))))