sheldon
sheldon copied to clipboard
:bowtie: Fast, configurable, shell plugin manager
sheldon
Fast, configurable, shell plugin manager
Features
- Plugins from Git repositories.
- Branch / tag / commit support.
- Submodule support.
- First class support for GitHub repositories.
- First class support for Gists.
- Arbitrary remote scripts or binary plugins.
- Local plugins.
- Inline plugins.
- Highly configurable install methods using handlebars templating.
- Shell agnostic, with sensible defaults for Zsh.
- Super-fast plugin loading and parallel installation. See benchmarks.
- Config file using TOML syntax.
- Clean
~/.zshrcor~/.bashrc(just add 1 line).
Table of Contents
- π¦ Installation
- Pre-built binaries
- Homebrew
- Cargo
- Building from source
- π Getting started
- Initializing
- Adding a plugin
- Loading plugins
- π» Command line interface
initlocksourceaddeditremove- Options
--color <when>--home <home>--config-dir <path>--data-dir <path>--config-file <path>--lock-file <path>--clone-dir <path>--download-dir <path>--profile <profile>- XDG directory structure
- Completions
- βοΈ Configuration
- Plugin sources
- Git
githubgistgit- Specifying a branch, tag, or commit
- Cloning with Git or SSH protocols
- Private Git repositories
- Remote
- Local
- Git
- Plugin options
useapplyprofiles
- Inline plugins
- Templates
- Custom templates
- Global options
shellmatchapply
- Plugin sources
- π‘ 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.
curl --proto '=https' -fLsS https://rossmacarthur.github.io/install/crate.sh \
| bash -s -- --repo rossmacarthur/sheldon --to ~/.local/bin
Alternatively, you can download an artifact directly from the the releases page.
Homebrew
Sheldon can be installed using Homebrew.
brew install sheldon
Cargo
Sheldon can be installed from Crates.io using Cargo, the Rust package manager.
cargo install sheldon
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.
git clone https://github.com/rossmacarthur/sheldon.git
cd sheldon
cargo build --release
The binary will be found at target/release/sheldon.
π Getting started
Initializing
Sheldon works by specifying plugin information in a TOML
configuration file, plugins.toml. You can initialize this file by running
sheldon init.
sheldon init --shell bash
or
sheldon init --shell zsh
This will create plugins.toml under ~/.sheldon or, if defined,
$XDG_CONFIG_HOME/sheldon. 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 append the following to the Sheldon config file.
# ~/.sheldon/plugins.toml
[plugins.base16]
github = "chriskempson/base16-shell"
Or use the add command to automatically add it.
sheldon add base16 --github chriskempson/base16-shell
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
eval "$(sheldon source)"
π» Command line interface
Sheldon has three different types of commands.
initinitializes a new config file.lockandsourcedeal with plugin downloading, installation, and generation of shell source code.add,edit, andremoveautomate editing of the config file.
init
This command initializes a new config file. If a config file exists then this command does nothing.
For example
sheldon init
Or you can specify the shell.
sheldon init --shell bash
or
sheldon init --shell zsh
lock
The lock command installs the plugins sources and generates the lock file
(~/.sheldon/plugins.lock). Rerunning this command without any extra options
will not reinstall plugin sources, just verify that they are correctly
installed. It will always regenerate the lock file.
sheldon lock
To update all plugin sources you can use the --update flag.
sheldon lock --update
To force a reinstall of all plugin sources you can use the --reinstall flag.
sheldon lock --reinstall
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 eval
command.
eval "$(sheldon source)"
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.
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.
sheldon add my-repo --git https://github.com/owner/repo.git
An example usage of this command for each source type is shown in the Configuration 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 sheldon edit
Or with Visual Studio Code
EDITOR="code --wait" sheldon edit
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.
sheldon remove my-repo
Options
Sheldon accepts the following global command line options and environment
variables. You can also view all options by running Sheldon with -h or
--help. The value that will be used for the option follows the following
priority.
- Command line option.
- Environment variable.
- Default value.
--color <when>
Set the output coloring.
always: Always use colored output.auto: Automatically determine whether to use colored output (default).never: Never use colored output.
--home <home>
Environment variable: HOME
Set the users home directory. This is usually automatically detected but might be required if you are using an obscure operating system.
--config-dir <path>
Environment variable: SHELDON_CONFIG_DIR
Set the config directory where config will store the configuration file. If
Sheldon detects an XDG directory structure (as described
below) then this will default to
XDG_CONFIG_HOME/sheldon otherwise it will default to <home>/.sheldon where
<home> is the users home directory.
--data-dir <path>
Environment variable: SHELDON_DATA_DIR
Set the data directory where plugins will be downloaded to. If Sheldon detects
an XDG directory structure (as described below) then
this will default to XDG_DATA_HOME/sheldon otherwise it will default to
<home>/.sheldon where <home> is the users home directory.
--config-file <path>
Environment variable: SHELDON_CONFIG_FILE
Set the path to the config file. This defaults to <config-dir>/plugins.toml
where <config-dir> is the config directory.
--lock-file <path>
Environment variable: SHELDON_LOCK_FILE
Set the path to the lock file. This defaults to <data-dir>/plugins.lock where
<data-dir> is the data directory.
--clone-dir <path>
Environment variable: SHELDON_CLONE_DIR
Set the path to the directory where Git plugins will be cloned to. This defaults
to <data-dir>/repos where <data-dir> is the data directory.
--download-dir <path>
Environment variable: SHELDON_DOWNLOAD_DIR
Set the path to the directory where non-Git plugins will be downloaded to. This
defaults to <data-dir>/repos where <data-dir> is the data directory.
--profile <profile>
Environment variable: SHELDON_PROFILE
Specify the profile to match plugins against. Plugins which have profiles configured will only get loaded if one of the given profiles matches the profile.
XDG directory structure
If any of the following XDG environment variables are set then the default config and data directories will change as specified above.
XDG_CONFIG_HOME, defaults to<home>/.configwhere<home>is the users home directory.XDG_CACHE_HOMEXDG_DATA_HOME, defaults to<home>/.local/sharewhere<home>is the users home directory.XDG_DATA_DIRSXDG_CONFIG_DIRS
Completions
Shell completion scripts for Bash and Zsh are available. If Sheldon was installed via Homebrew then the completions should have been installed automatically.
They can also be generated by Sheldon using the completions subcommand which
will output the completions to stdout. Refer to your specific shell
documentation for more details on how to install these.
sheldon completions --shell bash > /path/to/completions/sheldon.bash
or
sheldon completions --shell zsh > /path/to/completions/_sheldon
βοΈ 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
# ββββ΄ββ
[plugins.base16]
github = "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 data 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.
[plugins.example]
github = "owner/repo"
Or run add with the --github option.
sheldon add example --github owner/repo
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.
[plugins.example]
gist = "579d02802b1cc17baed07753d09f5009"
Or run add with the --gist option.
sheldon add example --gist 579d02802b1cc17baed07753d09f5009
git
A Git source must set the git field and specify the URL to clone. Add the
following to the Sheldon config file.
[plugins.example]
git = "https://github.com/owner/repo"
Or run add with the --git option.
sheldon add example --git https://github.com/owner/repo
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.
[plugins.example]
github = "owner/repo"
tag = "v0.1.0"
Or run add with the --tag, --branch, or --rev option.
sheldon add example --github owner/repo --tag v0.1.0
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.
[plugins.example]
github = "owner/repo"
proto = "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).
[plugins.example]
git = "ssh://[email protected]/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.
[plugins.example]
remote = "https://github.com/owner/repo/raw/branch/plugin.zsh"
Or run add with the --remote option.
sheldon add example --remote https://github.com/owner/repo/raw/branch/plugin.zsh
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.
[plugins.example]
local = "~/Downloads/plugin"
Or run add with the --local option.
sheldon add example --local '~/Downloads/plugin'
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.
[plugins.example]
github = "owner/repo"
use = ["*.zsh"]
Or run add with the --use option when adding the plugin.
sheldon add example --github owner/repo --use '*.zsh'
apply
A list of template names to apply to this plugin. This defaults to the global
apply.
[plugins.example]
github = "owner/repo"
apply = ["source", "PATH"]
Or run add with the --apply option when adding the plugin.
sheldon add example --github owner/repo --apply source PATH
You can define your own custom templates to apply to your plugins.
profiles
A list of profiles this plugin should be used in. If this field is not given the plugin will be used regardless of the profile. Otherwise, the plugin is only used if the specified profile is included in the configured list of profiles.
Inline plugins
For convenience it also possible to define Inline plugins. An Inline plugin must
set the inline field and specify the raw source.
[plugins.example]
inline = 'example() { echo "Just an example of inline shell code" }'
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
PATHvariable.
If you are using Zsh then the following are also available.
- path: add the plugin directory to the
pathvariable. - fpath: add the plugin directory to the
fpathvariable.
As template strings in the config file they could be represented like the following.
[templates]
source = { value = 'source "{{ file }}"', each = true }
PATH = 'export PATH="{{ dir }}:$PATH"'
path = 'path=( "{{ dir }}" $path )'
fpath = '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.
[plugins.example]
github = "owner/repo"
apply = ["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. For 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 }}. -
One or more files. These are the matched files in the plugin directory either discovered using the the global
matchfield or specified as a plugin option withuse. These can be used in templates using{{ file }}. This information only makes sense in templates witheachset totrue. -
The Sheldon data directory. This directory can be used as
{{ data_dir }}.
To add or update a template add a new key to the [templates] table in the
config file. Take a look at the examples for some interesting
applications of this.
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.
shell = "bash"
or
shell = "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
match = [
"{{ 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
match = [
"{{ 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
apply = ["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.