Emacs 9 - Concatenating processes
Demo

Create a Simple Process
Emacs allows you to create background processes very easily. Consider you want to run a compilation process before you save a file. It would look like this:
(defun compile-after-save ()
"Start a process to compile a C file gcc using hard-coded parameters"
(let ((process-name "compile-test")
(filename (buffer-file-name)))
(start-process process-name process-name
"gcc" "-o"
(file-name-sans-extension (file-name-nondirectory filename))
filename)))Fair enough, we can run this function every time we save a file using M-x eval-expression and calling:
(add-hook 'after-save-hook 'compile-after-save nil t)It’s Done in Background
OK, now we have the compiled code, it would be nice to run the program. As I want to have nicely decoupled - and it’s a toy project just to show the concatenation of processes - I will listen to the process events and when this process finishes I will trigger a new process to run the program. Yay!
First let’s create a function that runs the code in a new process and display it in a new window. I created that function knowing it will be triggered by a process event.
In the code it verifies if the process event is the string finished\n and then starts a process to run the compiled file.
(defun run-after-compile (process event)
(let ((buffer (current-buffer)))
(princ
(format "Process: %s had the event '%s'" process event))
(if (equal event "finished\n")
(let ((process-name "run-test"))
(start-process process-name process-name
(format "%s" (file-name-sans-extension (buffer-file-name))))
(view-buffer-other-window process-name t)
(switch-to-buffer-other-frame buffer)))))Triggering the run function
To trigger the function we want to wait the compilation to complete and after that call the function. In Emacs subprocesses it is done using a sentinel to watch the events in the spawned process. I will store the process in a variable named after-save-compile-process.
We need to change the compilation function to set the variable to point to the compilation process and add the sentinel as follows:
(defvar after-save-compile-process)
;; and somewhere inside the function `compile-after-save` I add:
(setq after-save-compile-process
(start-process process-name process-name
"gcc" "-o"
(file-name-sans-extension (file-name-nondirectory filename))
filename))
(set-process-sentinel after-save-compile-process 'run-after-compile)Full implementation and usage
(defvar after-save-compile-process)
(defun compile-after-save ()
"Start a process to compile a C file gcc using hard-coded parameters"
(let ((process-name "compile-test")
(filename (buffer-file-name)))
(setq after-save-compile-process
(start-process process-name process-name
"gcc" "-o"
(file-name-sans-extension (file-name-nondirectory filename))
filename))
(set-process-sentinel after-save-compile-process 'run-after-compile)))
(defun run-after-compile (process event)
(let ((buffer (current-buffer)))
(princ
(format "Process: %s had the event '%s'" process event))
(if (equal event "finished\n")
(let ((process-name "run-test"))
(start-process process-name process-name
(format "%s" (file-name-sans-extension (buffer-file-name))))
(view-buffer-other-window process-name t)
(switch-to-buffer-other-frame buffer)))))Documentation
If you really wanna learn about subprocesses in Emacs, stop reading crappy blog posts and go the docs.