Emacs Lisp can start other programs, open network connections and talk to serial ports. It can also run several threads, parse JSON and be driven from a shell script without a display. This page lists these facilities, starting with the functions that run a program and wait, then the asynchronous process objects, then the rest.
Synchronous subprocesses
These functions start a program, wait for it to end, and return. Emacs does not handle other events meanwhile, except that C-g can interrupt.
| Function | Use |
|---|---|
call-process PROGRAM &optional INFILE DESTINATION DISPLAY &rest ARGS | run a program. INFILE is the file for its input. DESTINATION is nil (discard output), t (current buffer), a buffer or name, 0 (do not wait), or a list (STDOUT STDERR-FILE) to separate the error output. Returns the exit status, or a signal description string. |
call-process-region START END PROGRAM &optional DELETE DESTINATION DISPLAY &rest ARGS | the same, with a part of the buffer as input |
process-file, process-file-shell-command | like call-process, but honour file name handlers: the program runs on the machine of default-directory, including a remote one |
shell-command-to-string COMMAND | run a shell command line and return its output as a string |
process-lines PROGRAM &rest ARGS | the output as a list of lines; signals an error if the exit status is not 0. process-lines-ignore-status does not. |
shell-command | the command that runs a shell line (with & asynchronously) |
(with-temp-buffer
(call-process "git" nil t nil "rev-parse" "HEAD")
(string-trim (buffer-string)))
Asynchronous processes
make-process starts a program and returns a process object at once. The program runs alongside Emacs, whose output arrives while Emacs waits for input or is in accept-process-output. It takes keyword arguments:
| Keyword | Meaning |
|---|---|
:name | the name of the process object (required) |
:buffer | the buffer for output, or nil for none |
:command | a list: the program and its arguments, run without a shell |
:coding | a coding system, or a cons (DECODING . ENCODING) |
:noquery | non-nil means Emacs does not ask before exit when the process runs |
:stop | start the process stopped |
:connection-type | pty, pipe, or a cons (INPUT . OUTPUT); the default comes from process-connection-type |
:filter | a function (PROCESS STRING) called with output |
:sentinel | a function (PROCESS EVENT) called when the status changes |
:stderr | a buffer or a pipe process for the error output, which is otherwise mixed with the standard output |
:file-handler | non-nil makes the call use the file name handler of default-directory (for remote machines) |
start-process NAME BUFFER PROGRAM &rest ARGS is the older, shorter form, and start-file-process is the one that honours file name handlers. A pseudo-terminal (pty) makes the program think it talks to a terminal and merges the two output streams; a pipe keeps them separate and is more reliable for data. A process is a Lisp object, so a sentinel or a filter can use it to control the process.
(make-process
:name "ping"
:command '("ping" "-c" "3" "localhost")
:buffer "*ping*"
:noquery t
:filter (lambda (proc string)
(with-current-buffer (process-buffer proc)
(goto-char (point-max))
(insert string)))
:sentinel (lambda (proc event)
(message "%s: %s" (process-name proc) (string-trim event))))
| Function | Use |
|---|---|
process-send-string, process-send-region | send text to the input of the program |
process-send-eof | close its input |
process-status | a symbol (see below) |
process-exit-status | the exit code, or the signal number |
process-live-p | true while the process runs or the connection is open |
delete-process | kill the process or close the connection |
process-put, process-get | store and read your own properties on a process |
accept-process-output &optional PROCESS SECONDS | wait for output from a process and run its filter |
set-process-query-on-exit-flag | whether Emacs asks before exit |
process-coding-system, set-process-coding-system | read or change the coding systems |
set-process-filter, set-process-sentinel | change the filter and the sentinel |
signal-process, interrupt-process, kill-process, stop-process, continue-process | send signals |
| Status | Meaning |
|---|---|
run | running |
stop | stopped, but can continue |
exit | finished; process-exit-status has the code |
signal | ended by a signal |
open, closed | a network connection or serial port that is open, or closed |
connect, failed, listen | network: connecting, failed, and a server waiting for clients |
nil | the argument is not a process that exists |
When :stderr is a buffer, Emacs makes a hidden pseudo-process that reads the error output into that buffer. A filter is called with output in chunks that may stop in the middle of a line. A sentinel runs after a status change, with a string such as "finished\n" or "exited abnormally with code 1\n".
Environment
A program is looked up in the list exec-path, and its environment is process-environment, a list of "NAME=value" strings. The macro with-environment-variables (Emacs 28) binds some of them for its body: (with-environment-variables (("LANG" "C")) (shell-command-to-string "date")). getenv and setenv read and change them in Emacs itself.
Network connections
| Function | Use |
|---|---|
make-network-process | open a client or a server connection. Keywords include :name, :buffer, :host, :service (a port number or name), :server (non-nil listens), :type (nil for a stream, datagram or seqpacket), :family, :local for a Unix socket, :filter, :sentinel, :nowait, :noquery, :coding and :tls-parameters. |
open-network-stream NAME BUFFER HOST SERVICE &rest PARAMETERS | the higher-level function. The parameter :type takes plain, tls (encrypted from the first byte), starttls (switches to TLS during the exchange, with :end-of-command and :success to detect it), network (tries the options in order) or shell. |
network-lookup-address-info NAME &optional FAMILY | look up a host name: a list of address vectors (Emacs 27). From Emacs 29 it can also check a numeric address. |
make-serial-process | open a serial port: :port, :speed, :bytesize, :parity, :stopbits, :flowcontrol |
make-pipe-process | a process that is only a pipe inside Emacs, used for :stderr and for interprocess data |
process-contact, process-datagram-address, set-network-process-option | query and tune connections |
Threads
A thread runs Lisp code beside the main thread, but only one thread runs at a time. Threads are cooperative: control passes when the running thread waits (for a process, a mutex or a condition variable), calls thread-yield, or finishes. They share variables and buffers; a let binding of a variable is local to its thread.
| Function | Use |
|---|---|
make-thread FUNCTION &optional NAME | start a thread; the value is the thread object |
thread-join | wait for a thread, return its result |
thread-yield | let another thread run |
thread-signal | raise an error in another thread |
thread-live-p, current-thread, all-threads, thread-name | inspect threads |
make-mutex, mutex-lock, mutex-unlock, with-mutex | mutual exclusion; with-mutex is the macro form |
make-condition-variable, condition-wait, condition-notify | wait for a condition on a mutex |
From Emacs 31 make-thread has an argument to choose what happens when the current buffer of a thread is killed (“buffer disposition”), with thread-buffer-disposition and thread-set-buffer-disposition to read and set it. Timers are on Commands and modes.
JSON
Emacs has JSON functions built in (Emacs 27). From Emacs 30 they no longer depend on an external library, and json-available-p always returns true.
| Function | Use |
|---|---|
json-parse-string STRING &rest ARGS | parse a string. Keywords: :object-type (hash-table, the default, alist or plist), :array-type (array or list), :null-object (default :null), :false-object (default :false). Signals json-parse-error on bad input. |
json-parse-buffer | read the next value in the buffer at point |
json-serialize OBJECT &rest ARGS | make a unibyte string; takes :null-object and :false-object |
json-insert | insert the JSON text of an object at point |
Emacs 30 changed some details: repeated object keys are kept in alist and plist results, bad UTF-8 signals json-utf8-decode-error, and integers of any size are accepted.
(json-parse-string "{\"a\": [1, 2, null]}" :object-type 'alist :array-type 'list)
;; => ((a 1 2 :null))
(json-serialize '((a . 1) (b . "x")))
System interaction and batch mode
| Name | Use |
|---|---|
getenv, setenv | read and set an environment variable of Emacs |
system-type | a symbol: gnu/linux, darwin, windows-nt, berkeley-unix, cygwin, ms-dos, android and others |
emacs-pid | the process number of Emacs |
kill-emacs &optional ARG | exit; an integer is the exit code of the program |
noninteractive | non-nil in batch mode |
command-line-args, command-line-args-left | the full command line, and the arguments not yet handled |
Batch mode runs Emacs with no display. emacs --batch -l file.el loads a file and exits when done; --eval and -f run a form and a function. Messages go to standard error and princ to standard output. The option --script FILE loads a file as a script, and so does -x; from Emacs 31 the files loaded with -x and --script use lexical binding. A script starts with a line such as #!/usr/bin/env -S emacs --script (File structure). A script that needs its own arguments reads them from command-line-args-left and removes them:
#!/usr/bin/env -S emacs --script
;;; -*- lexical-binding: t -*-
(while command-line-args-left
(princ (format "arg: %s\n" (pop command-line-args-left))))
Not described
Known, not yet covered
- Reference: dynamic modules are named only: a shared library that includes
emacs-module.his loaded withmodule-load, or byload; the C API is not described. D-Bus (dbus-call-methodand friends) is named only. - Reference: the SQLite functions (
sqlite-open,sqlite-execute,sqlite-select), built in when Emacs is built with SQLite (Emacs 29), are named only. - Reference: the rest of the options of
make-network-process(for example:tls-parametersand the options set byset-network-process-option), the process filter details (process-filter-multibyte-p), signals and the pty settings are summarised.
Unknown
- The Emacs version that added threads and the
-xoption: the reference sources used here do not state it.
See also
- Files – file name handlers and remote files
- Commands and modes – timers and hooks
- Packages and autoloads –
loadof dynamic modules - Processes – the manual chapter
- Threads – the manual section on threads
- Parsing and generating JSON values – the manual section