Features
- Can manage virtually anything.
- Any Git repository.
- Branch / tag / commit support.
- Submodule support.
- First class support for GitHub repositories.
- First class support for Gists.
- Arbitrary remote scripts or binaries.
- Local plugins.
- Inline plugins.
- Any Git repository.
- Highly configurable install methods using handlebars templating.
- Shell agnostic, with sensible defaults for Zsh.
- Super-fast parallel installation.
- Config file using TOML syntax.
- Lock file for much faster loading of plugins.
- Clean
~/.zshrc
or~/.bashrc
(just add 1 line).
Table of Contents
- Installation
- Getting started
- Command line interface
- Configuration: Plugin sources
- Configuration: Plugin options
- Configuration: Inline plugins
- Configuration: Templates
- Configuration: Global options
- Examples
- License
Installation
Pre-built binaries
Pre-built binaries for Linux (x86-64, aarch64, armv7) and macOS (x86-64) are
provided. The following script can be used to automatically detect your host
system, download the required artefact, and extract the sheldon
binary to the
given directory.
|
Alternatively, you can download an artifact directly from the the releases page.
Homebrew
Sheldon can be installed using Homebrew.
Cargo
Sheldon can be installed from Crates.io using Cargo, the Rust package manager.
Building from source
Sheldon is written in Rust, so to install it from source you will first need to install Rust and Cargo using rustup. Then you can run the following to build Sheldon.
The binary will be found at target/release/sheldon
.
Getting started
Initializing
Sheldon works by specifying plugin information in a TOML
configuration file. You can initialize this file by running sheldon init
.
or
This will create the ~/.sheldon
directory with an empty plugins.toml
file.
You can either edit this file directly or use the provided command line
interface to add or remove plugins.
Adding a plugin
To add your first plugin add the following to the Sheldon config file.
# ~/.sheldon/plugins.toml
[]
= "chriskempson/base16-shell"
Or use the add
command to automatically add it.
The first argument given here base16
is a unique name for the plugin. The
--github
option specifies that we want Sheldon to manage a clone of the
https://github.com/chriskempson/base16-shell
repository.
Loading plugins
You can then use sheldon source
to install this plugin, generate a lock file,
and print out the shell script to source. Simply add the following to your
~/.zshrc
or ~/.bashrc
file.
# ~/.zshrc or ~/.bashrc
Command line interface
Sheldon has three different types of commands.
init
initializes a new config file.lock
andsource
deal with plugin downloading, installation, and generation of shell source code.add
,edit
, andremove
automate editing of the config file.
lock
The lock
command installs the plugins sources and generates the lock file
(~/.sheldon/plugins.lock
). Rerunning this command will not reinstall plugin
sources, just verify that they are correctly installed. It will always
regenerate the lock file.
To update all plugin sources you can use the --update
flag.
To force a reinstall of all plugin sources you can use the --reinstall
flag.
source
This command generates the shell script. This command will first check if there
is an up to date lock file, if not, then it will first do the equivalent of the
lock command above. This command is usually used with the built-in shell
source
command.
But you can also run it directly to inspect the output. The output of this command is highly configurable. You can define your own custom templates to apply to your plugins.
init
This command initializes a new config file. If a config file exists then this command does nothing.
For example
Or you can specify the shell.
add
This command adds a new plugin to the config file. It does nothing else but edit the config file. In the following command we add a GitHub repository as a source.
An example usage of this command for each source type is shown in the Configuration: plugin sources section.
edit
This command will open the config file in the default editor and only overwrite
the contents if the updated config file is valid. To override the editor that is
used you should set the EDITOR
environment variable.
For example using vim
EDITOR=vim
Or with Visual Studio Code
EDITOR="code --wait"
remove
This command removes a plugin from the config file. It does nothing else but
edit the config file. In the following command we remove the plugin with name
my-repo
.
Flags
Sheldon accepts the following global command line flags.
Flag | Description |
---|---|
-q , --quiet |
Suppress any informational output |
-v , --verbose |
Use verbose output |
--no-color |
Do not use ANSI colored output |
-h , --help |
Show the help message and exit |
-V , --version |
Show the version and exit |
Options
Sheldon accepts the following global command line options.
Option | Environment variable | Description |
---|---|---|
--home <path> |
HOME |
Set the home directory. (default: auto) |
--root <path> |
SHELDON_ROOT |
Set the root directory. (default: <home>/.sheldon ) |
--config-file <path> |
SHELDON_CONFIG_FILE |
Set the config file. (default: <root>/plugins.toml ) |
--lock-file <path> |
SHELDON_LOCK_FILE |
Set the lock file. (default: <config-file>.lock ) |
--clone-dir <path> |
SHELDON_CLONE_DIR |
Set the clone directory. (default: <root>/repos ) |
--download-dir <path> |
SHELDON_DOWNLOAD_DIR |
Set the download directory. (default: <root>/downloads ) |
The priority order for setting these values is the following
- Command line option.
- Environment variable.
- Default value.
Configuration: Plugin sources
A plugin is defined by adding a new unique name to the plugins
table in the
TOML config file. This can be done by either editing the file
directly or using the provided Sheldon commands. A plugin must provide the
location of the source. There are three types of sources, each kind is described
in this section. A plugin may only specify one source type.
# ~/.sheldon/plugins.toml
# ┌─ Unique name for the plugin
# ┌──┴─┐
[]
= "chriskempson/base16-shell"
# └─────┬────┘ └─────┬────┘
# │ └─ GitHub repository name
# └─ GitHub user or organization
Git
Git sources specify a remote Git repository that will be cloned to the Sheldon root directory. There are three flavors of Git sources.
github
A GitHub source must set the github
field and specify the repository. This
should be the username or organization and the repository name separated by a
forward slash. Add the following to the Sheldon config file.
[]
= "owner/repo"
Or run add
with the --github
option.
gist
A Gist source must set the gist
field and specify the repository. This should
be the hash or username and hash of the Gist. Add the following to the Sheldon
config file.
[]
= "579d02802b1cc17baed07753d09f5009"
Or run add
with the --gist
option.
git
A Git source must set the git
field and specify the URL to clone. Add the
following to the Sheldon config file.
[]
= "https://github.com/owner/repo"
Or run add
with the --git
option.
Specifying a branch, tag, or commit
All Git sources also allow setting of one of the branch
, tag
or rev
fields. Sheldon will then checkout the repository at this reference.
[]
= "owner/repo"
= "v0.1.0"
Or run add
with the --tag
, --branch
, or --rev
option.
Cloning with Git or SSH protocols
GitHub and Gist sources are cloned using HTTPS by default. You can specify that
Git or SSH should be used by setting the proto
field to the protocol type.
This must be one of git
, https
, or ssh
.
[]
= "owner/repo"
= "ssh"
For a plain Git source you should specify the URL with a git://
or ssh://
.
For SSH you will need to specify the username as well (it is git
for GitHub).
[]
= "ssh://git@github.com/owner/repo"
Private Git repositories
Currently Sheldon only supports authentication when cloning using SSH and requires an SSH agent to provide credentials. This means if you have a plugin source that is a private repository you will have to use the SSH protocol for cloning.
Remote
Remote sources specify a remote file that will be downloaded by Sheldon. A
remote source must set the remote
field and specify the URL. Add the following
to the Sheldon config file.
[]
= "https://github.com/owner/repo/raw/master/plugin.zsh"
Or run add
with the --remote
option.
Local
Local sources reference local directories. A local source must set the local
field and specify a directory. Tildes may be used and will be expanded to the
current user's home directory. Add the following to the Sheldon config file.
[]
= "~/Downloads/plugin"
Or run add
with the --local
option.
Configuration: Plugin options
These are options that are common to all the above plugins.
use
A list of files / globs to use in the plugin's source directory. If this field
is not given then the first pattern in the global match
field that
matches any files will be used. Add the following to the Sheldon config file.
[]
= "owner/repo"
= ["*.zsh"]
Or run add
with the --use
option when adding the plugin.
apply
A list of template names to apply to this plugin. This defaults to the global
apply
.
[]
= "owner/repo"
= ["source", "PATH"]
Or run add
with the --apply
option when adding the plugin.
You can define your own custom templates to apply to your plugins.
Configuration: Inline plugins
For convenience it also possible to define Inline plugins. An Inline plugin must
set the inline
field and specify the raw source.
[]
= 'example() { echo "Just an example of inline shell code" }'
Configuration: Templates
A template defines how the shell source for a particular plugin is generated.
For example the PATH template adds the plugin directory to the shell PATH
variable. A template will be applied to a plugin if you add the template name to
the apply
field on a plugin.
Available built-in templates are different depending on what shell you are using. The following are available for both Bash and Zsh.
- source: source each file in a plugin.
- PATH: add the plugin directory to the
PATH
variable.
If you are using Zsh then the following are also available.
- path: add the plugin directory to the
path
variable. - fpath: add the plugin directory to the
fpath
variable.
As template strings in the config file they could be represented like the following.
[]
= { = 'source "{{ file }}"', = true }
= 'export PATH="{{ dir }}:$PATH"'
= 'path=( "{{ dir }}" $path )'
= 'fpath=( "{{ dir }}" $fpath )'
For example if we change the apply
field for the below plugin, it will only
add the plugin directory to the PATH
and append it to the fpath
. The plugin
will not be sourced.
[]
= "owner/repo"
= ["PATH", "fpath"]
The each
value, as used in the source
template above, specifies that the
template should be applied to each matched file for the plugin. This defaults to
false
.
Custom templates
It is possible to create your own custom templates, and you can even override the built-in ones.
Plugins all have the following information that can be used in templates
-
A unique name. This is completely arbitrary, and it is the value specified for the plugin in the plugins table. However, it is often the name of the plugin, so it can be useful to use this name in templates with
{{ name }}
. -
A directory. In git sources this is the location of the cloned repository, for local sources, it is the directory specified. This directory can be used in templates with
{{ dir }}
. -
Zero or more files. These are the matched files in the plugin directory either discovered using the the global
match
field or specified as a plugin option withuse
. These can be used in templates using{{ file }}
. You can use the following global information in templates -
The sheldon root. This folder can be used as
{{ root }}
.
Example: symlinking files
Lets say we would like a template to symlink files into the
~/.sheldon/functions
directory. We could create a new template with name
function, like this
[]
= { = 'ln -sf "{{ file }}" "~/.zsh/functions/{{ name }}"', = true }
It can then be applied to the plugin like this
[]
= "owner/repo"
= ["function"]
Example: overriding the PATH template
The built-in PATH template adds the directory path to the beginning of the
PATH
variable, we might want to change it to the be added at the end. We could
do this like this
[]
= 'export PATH="$PATH:{{ dir }}"'
You can then apply it to the plugin like this
[]
= "owner/repo"
= ["source", "PATH"]
Note: this would change the behavior of PATH for all plugins using it.
Configuration: Global options
shell
Indicates the shell that you are using. This setting will affect the default
values for several global config settings. This includes the global
match
setting and the available templates. This defaults to zsh
.
= "bash"
or
= "zsh"
match
A list of glob patterns to match against a plugin's contents. The first pattern
that matches any files will be used by default as a plugin's use
field. This
defaults to
= [
"{{ name }}.plugin.zsh",
"{{ name }}.zsh",
"{{ name }}.sh",
"{{ name }}.zsh-theme",
"*.plugin.zsh",
"*.zsh",
"*.sh",
"*.zsh-theme"
]
If the shell is Bash then this defaults to
= [
"{{ name }}.plugin.bash",
"{{ name }}.plugin.sh",
"{{ name }}.bash",
"{{ name }}.sh",
"*.plugin.bash",
"*.plugin.sh",
"*.bash",
"*.sh"
]
apply
A list of template names to apply to all plugins by default (see
apply
). This defaults to
= ["source"]
Examples
You can find many examples including deferred loading of plugins in the documentation.
License
Licensed under either of
- Apache License, Version 2.0 (LICENSE-APACHE or http://www.apache.org/licenses/LICENSE-2.0)
- MIT license (LICENSE-MIT or http://opensource.org/licenses/MIT)
at your option.