Conner is a Command Runner for GNU Emacs.
Warning
Conner is currently alpha software. Nothing is set in stone, so the API or the .conner file format may change. As such, until I release 1.0, I reserve the right to break configs.
Conner allows you to define custom commands tailored to your projects' needs. Whether it's compiling, running, testing, prettifying, monitoring changes, debugging, installing, or any other task specific to your workflow, Conner makes it easy to integrate with Emacs.
Commands are configured in a .conner
file, typically located at the
root of your project. Inside this file, you'll define a Lisp object
containing a list of command names, their respective commands, and
their types.
Integration with project.el
enables seamless execution of these
commands within Emacs, either on arbitrary directories or
automatically detecting the current project's root.
Additionally, Conner also has support for .env
files. By default,
Conner will look in the root directory of your project for a .env
file and load any environment variables found within. These variables
are then accessible to Conner commands, and won't pollute the regular
Emacs session.
Conner is configurable, so you can add your own command types if what's available doesn't quite suit your needs.
- Integrated command editor which streamlines the experience.
- Project aware thanks to
project.el
integration. - Allows for custom command runners.
- Format specifiers let you get information at run-time.
- Loading of env variables via
.env
files. - Per-command environment overrides.
- Change working directory.
- Meta command type allows for complex setups.
- User-facing functions for CRUD operations on commands.
To add a command, simply execute M-x conner-add-project-command
or
M-x conner-add-command
. A new buffer will open where you can edit
your command. These are the available keys:
:name
The name of the command. Will be used to identify the command. Most runners use it to name their buffers. Must be a string.:command
The command to run. Its interpretation will vary depending on the runner. Most runners support format specifiers that are calculated at runtime. Readconner-expand-command
for details. Must be defined.:type
The type decides which runner to call when executing the command. Seeconner-command-types-alist
for available types. Must be a string.:workdir
Specifies a working directory from where to run the command. The directory is relative to the root directory of the project. Must be a string.:environment
List of strings containing environment variables in the form of "KEY=value". These variables will be accesible to the command they are declared in only. Must be a list.
Note that :name
, :command
, and :type
are the only keys that must
be defined. The rest are optional. If you wish to not provide a value,
you must either provide nil
or remove them altogheter. A key with an
emtpy value is not a valid plist.
Once defined, run the command using M-x conner-run-project-command
or M-x conner-run-command
.
For those who prefer keeping their repositories free from IDE-specific
files, Conner offers support for "local" Conner files. These files are
stored in your emacs-user-directory
.
Whenever you invoke conner-run-command
, it will load both the
project .conner
file, as well as the associated file for that
directory stored in your emacs-user-directory
.
To utilize this feature, simply prefix any user-facing function with
C-u
. Note that conner-run-command
always reads both local and
project files.
If you prefer using local files by default, set the variable
conner-default-file-behavior
to 'local
. This setting makes all
functions default to local files, with the prefix argument allowing
access to project files.
While Conner ships with a variety of command types already, you can define custom types tailored to your requirements. Adding a custom command type is straightforward:
- Define a function to execute the command.
- Register the function in
conner-command-types-alist
.
Custom command functions receive the plist of the command, which
contains all the data saved in the Conner file, and the root
directory. This directory corresponds to the directory with which
conner-run-command
was originally invoked.
Below is an example of a command type that prints the command plist along with the root directory.
(defun my-conner-command-type-print (plist root-dir)
"Print command PLIST and ROOT-DIR."
(message "Command plist: %s\nRoot dir: %s" plist root-dir))
(add-to-list 'conner-command-types-alist
`("print" ,#'my-conner-command-type-print))
You will then be able to define commands with type print
.
Do make sure to use the result of conner-expand-command
as the
command to run to ensure each format specifier gets expanded. If not
applicable to your runner, it can of course be omitted.
The processing of .env
files in Conner is based on diasjorge's
load-env-vars.