Using synchronous processes
If you want to adhere to synchronous processes (for example, using call-process ), you need to call (redisplay) after each call to execute-in-buffer to display, which will be updated, and the output should be visible (see also this question for more detailed information). However, the output of each command will not be displayed until the process is completed, and emacs will hang during the execution of external processes.
Using asynchronous processes
Using asynchronous processes is a bit more complicated, but avoids Emacs freezing during command execution, which also solves the problem of re-rendering. The hard part here is to consistently connect all the teams. Here is some elisp that should do the trick:
(defun execute-commands (buffer &rest commands) "Execute a list of shell commands sequentially" (with-current-buffer buffer (set (make-local-variable 'commands-list) commands) (start-next-command))) (defun start-next-command () "Run the first command in the list" (if (null commands-list) (insert "\nDone.") (let ((command (car commands-list))) (setq commands-list (cdr commands-list)) (insert (format ">>> %s\n" command)) (let ((process (start-process-shell-command command (current-buffer) command))) (set-process-sentinel process 'sentinel))))) (defun sentinel (pe) "After a process exited, call `start-next-command' again" (let ((buffer (process-buffer p))) (when (not (null buffer)) (with-current-buffer buffer ;(insert (format "Command `%s' %s" pe) ) (start-next-command))))) ;; Example use (with-current-buffer (get-buffer-create "*output*") (erase-buffer)) (execute-commands "*output*" "echo 1" "sleep 1" "echo 2; sleep 1; echo 3" "ls /")
source share