Wrappers functions around standard Emacs shell API functions, with saner defaults and additional keyword arguments.
They are split into 3 packages:
-
friendly-shell-command
: wraps shell command API from simple.el (blog post) -
friendly-shell
: wraps interactive shell API from shell.el (blog post) -
friendly-remote-shell
: command for human-friendly spawning of remote shells
Examples can be found in examples.md.
They rely heavily on package with-shell-interpreter.
friendly-remote-shell
relies additionally on helper package friendly-tramp-path.
NB: These packages used to be called prf-shell-command
, prf-shell
and prf-remote-shell
. You can still grab the legacy code with version 0.1.0.
All the packages are available on Melpa.
(use-package friendly-shell-command)
(use-package friendly-shell)
(use-package friendly-remote-shell)
Each of functions provided by the package have the same behavior as their wrapped counterparts but come with additional keyword arguments.
Here are the additional keywords that are shared by all the wrapper functions:
keyword argument | implicit var being let-bound | description |
---|---|---|
:path | default-directory |
The path from which to launch command / shell. |
:interpreter | explicit-shell-file-name / shell-file-name |
Name or absolute path of shell interpreter executable. |
:interpreter-args | explicit-INTEPRETER-args |
Login args to call interpreter with for login. |
:command-switch | shell-command-switch |
Command switch arg for asking interpreter to run a shell command. |
:w32-arg-quote | w32-quote-process-args |
Character to use for quoting shell arguments (only on the Windows build of Emacs) |
If :path is remote, the command will be executed with the remote host interpeter.
See README of with-shell-interpreter for more details.
Concrete examples can be found in examples.md.
Helpers functions to create commands launching (non-interactive) shell commands.
- friendly-shell-command | friendly-shell-command-to-string
(cmd & :path :interpreter :command-switch)
- friendly-shell-command | friendly-shell-command
(cmd & :output-buffer :error-buffer :path :interpreter :interpreter-args :command-switch :callback :kill-buffer)
- friendly-shell-command | friendly-shell-command-async
(cmd & :output-buffer :error-buffer :path :interpreter :interpreter-args :command-switch :callback :kill-buffer :sentinel)
Command for spawning interactive shells or helper function to create new interactive shell-spawning commands.
- friendly-shell | friendly-shell
(& :path :interpreter :interpreter-args :command-switch :w32-arg-quote)
- friendly-remote-shell | friendly-remote-shell
(& :path :interpreter :interpreter-args :command-switch :w32-arg-quote)
Emacs provides some standard function for launching shell commands (from simple.el
):
function | execution | return value | spawned buffers |
---|---|---|---|
shell-command-to-string (command) |
synchronous | stdout | |
shell-command (command & output-buffer error-buffer) |
synchronous | return code | stdout and stderr |
async-shell-command (command & output-buffer error-buffer) |
asynchronous | window containing output-buffer | stdout and stderr |
Package friendly-shell-command
provide a wrapper around each of those.
They have the same behavior (sync/async, return value, spawned buffers) as their wrapped counterparts.
(cmd & :path :interpreter :command-switch)
Calls CMD with shell-command-to-string
with :interpreter at given :path.
(cmd & :output-buffer :error-buffer :path :interpreter :interpreter-args :command-switch :callback :kill-buffer)
Calls CMD synchronously with shell-command
with :interpreter at given :path.
In addition to the common keywords, the following additional keyword can be used:
keyword | description | default value |
---|---|---|
:output-buffer | Buffer to output to. | *Shell Command Output* |
:error-buffer | Buffer to output stderr to. | value of :output-buffer |
:kill-buffer | If non-nil, will output buffer after execution | nil |
:callback | Function to run at the end of the command execution. | n/a |
Please note that :callback
function should not take any argument (0-arity).
(cmd & :output-buffer :error-buffer :path :interpreter :interpreter-args :command-switch :callback :kill-buffer :sentinel)
Calls CMD asynchronously with async-shell-command
with :interpreter at given :path.
In addition to the common keywords, the following additional keyword can be used:
keyword | description | default value |
---|---|---|
:output-buffer | Buffer to output to. | *Shell Command Output* |
:error-buffer | Buffer to output stderr to. | value of :output-buffer |
:kill-buffer | If non-nil, will output buffer after execution | nil |
:callback | Function to run at the end of the command execution. | n/a |
:sentinel | Process sentinel to bind to the command process. | n/a |
Please note that :callback function should not take any argument (0-arity).
For the :sentinel argument, you can read more about process sentinels in the Emacs manual.
(& :path :interpreter :interpreter-args :command-switch :w32-arg-quote)
Spawn a shell with shell
with :interpreter at given :path.
When used as a command (i.e. called interactively), spawns a shell at current location (default-directory
) with the default interpreter (shell-file-name
or with-shell-interpreter-default-remote
if on a remote server).
Contrarily to default shell
behavior, the value of interpreter and its args are kept as buffer-local vars (explicit-shell-file-name
, explicit-<interpreter>-args
,shell-command-switch
...).
This allows reusing the same interpreter config when launching shell commands from the spawned buffer.
(& :path :interpreter :interpreter-args :command-switch :w32-arg-quote)
Same as friendly-shell
but accept a more permissive remote path format (thanks to p3r7/friendly-tramp-path).
If called as a command, will prompt user for :path, assuming it's a remote host.
For example:
M-x friendly-shell
Host: pi@raspberry
I highly encourage to use package shx which provides various enhancement for interactive shell buffers.
One of the major improvement is the ability to resurrect dead shell buffers.
Howard has a lot of goodies related to remote interactive shells and eshell.
Notably:
- command eshell-here that behaves like
friendly-shell
called interactively, except spawning eshell instead of shell. - command eshell-there that is very similar to
friendly-remote-shell
, except spawning eshell instead of shell - various commands for spawning remote shells given host aliases. He also defines a
remote-shell-command
that behaves likefriendly-shell-command
.
This package provides command better-shell-for-current-dir
which is very similar to friendly-shell
called interactively. One key difference is that it implements a mechanism for reusing existing shell buffers if appropriate.
It also provides command better-shell-remote-open
which behaves like friendly-remote-shell
except it provides autocompletion from ~/.ssh/known_hosts
.
Bindings between term.el and TRAMP to ease the creation of remote term buffers.
This code uses form feeds (^L
character) as separators.
Either package form-feed or page-break-lines makes them appear as intended.