_ _ _
/\_\ /\_\ /\_\
\/_/ \/_/ \/_/ …because $HOME is where the <3 is!
Ellipsis is a package manager for dotfiles.
- Creating new packages is trivial (any git repository is already a package).
- Modular configuration files are easier to maintain and share with others.
- Allows you to quickly see which dotfiles have been modified, and keep them updated and in-sync across systems.
- Adding new dotfiles to your collection can be automated with
ellipsis add
. - Cross platform, known to work on Mac OS X, Linux, FreeBSD and even Cygwin.
- Large test suite to ensure your
$HOME
doesn't get ravaged. - Completely customizable.
- Works with existing dotfiles!
Clone and symlink or use handy-dandy installer:
$ curl -sL ellipsis.sh | sh
...no you didn't read that wrong, this website also doubles as the installer
You can also specify which packages to install by setting the PACKAGES
variable, i.e.:
$ curl -sL ellipsis.sh | PACKAGES='vim zsh' sh
Add ~/.ellipsis/bin
to your $PATH
(or symlink somewhere convenient) and
start managing your dotfiles in style :)
Ellipsis comes with no dotfiles out of the box. To install packages, use
ellipsis install
. Packages can be specified by github-user/repo or full
ssh/git/http(s) urls:
$ ellipsis install ssh://github.com/zeekay/private.git
$ ellipsis install zeekay/vim
$ ellipsis install zsh
...all work. By convention username/package
and package
are aliases for
https://github.com/username/dot-package.
Full usage available via ellipsis
executable:
$ ellipsis -h
Usage: ellipsis <command>
Options:
-h, --help show help
-v, --version show version
Commands:
new create a new package
edit edit an installed package
add add new dotfile to package
install install new package
uninstall uninstall package
link link package
unlink unlink package
broken list any broken symlinks
clean rm broken symlinks
installed list installed packages
links show symlinks installed by package(s)
pull git pull package(s)
push git push package(s)
status show status of package(s)
publish publish package to repository
search search package repository
You can customize ellipsis by exporting a few different variables:
Customizes whose dotfiles are installed when you ellipsis install
without
specifiying user or a full repo url. Defaults to $(git config github.user)
or
zeekay
.
Customize location of ellipsis repo cloned during a curl-based install. Defaults
to https://github.com/zeekay/ellipsis
.
Customizes which protocol new packages are cloned with, you can specify
https
,ssh
, git
. Defaults to https
.
Customize which folder files are symlinked into, defaults to $HOME
. (Mostly
useful for testing).
Customize where ellipsis lives on your filesystem, defaults to ~/.ellipsis
.
Customize where ellipsis installs packages on your filesystem, defaults to
~/.ellipsis/packages
.
export ELLIPSIS_USER="zeekay"
export ELLIPSIS_SSH="ssh"
export ELLIPSIS_PATH="~/.el"
A package is any repo with files you want to symlink into $ELLIPSIS_PATH
(typically $HOME
). By default all of a respository's non-hidden files (read:
not beginning with a .
) will naively be linked into place, with the exception
of a few common text files (README
, LICENSE
, etc).
You can customize how ellipsis interacts with your package by adding an
ellipsis.sh
file to the root of your project. Here's an example of a complete
ellipsis.sh
file:
#!/usr/bin/env bash
Yep, that's it :) If all you want to do is symlink some files into $HOME
,
adding an ellipsis.sh
to your package is completely optional. But what if you
need more? That's where hooks come in...
Hooks allow you to control how ellipis interacts with your package, and how
various commands are executed against your package. Say for instance you wanted
to run the installer for your favorite zsh
framework, you could define a pkg.install
hook like this:
#!/usr/bin/env bash
pkg.install() {
utils.run_installer 'https://raw.github.com/zeekay/zeesh/master/scripts/install.sh'
}
When you ellipsis install
a package, ellipsis:
git clone
's the package into~/.ellipsis/packages
.- Changes the current working dir to the package.
- Sets
$PKG_NAME
and$PKG_PATH
. - Sources the package's
ellipsis.sh
(if one exists). - Executes the package's
pkg.install
hook orhooks.install
(the default hook).
Here's a more complete example (from zeekay/files):
#!/usr/bin/env bash
pkg.install() {
fs.link_files common
case $(os.platform) in
cygwin)
fs.link_files platform/cygwin
;;
osx)
fs.link_files platform/osx
;;
freebsd)
fs.link_files platform/freebsd
;;
linux)
fs.link_files platform/linux
;;
esac
}
...and here's a slightly more complex example (from zeekay/vim):
#!/usr/bin/env bash
pkg.install() {
files=(gvimrc vimrc vimgitrc vimpagerrc)
for file in ${files[@]}; do
fs.link_file $file
done
# link module into ~/.vim
fs.link_file $PKG_PATH
# install dependencies
cd ~/.vim/addons
git.clone https://github.com/zeekay/vice
git.clone https://github.com/MarcWeber/vim-addon-manager
}
helper() {
# run command for ourselves
$1
# run command for each addon
for addon in ~/.vim/addons/*; do
cd $addon
$1 $addon
done
}
pkg.pull() {
helper git.pull
}
pkg.status() {
helper hooks.status
}
pkg.push() {
git.push
# git push only repos where we have push permission
for addon in ~/.vim/addons/*; do
if [ "$(cat $addon/.git/config | grep $ELLIPSIS_USER)" ]; then
cd $addon
git.push $addon
fi
done
}
The hooks available in your ellipsis.sh
are:
Customizes how a files is added to your package.
Customize how package is installed. By default the pkg.link hooks is run.
Customize how package is listed as installed.
Customizes which files are linked into $ELLIPSIS_HOME
.
Customizes which files are detected as symlinks.
Customize how how changes are pulled in when ellipsis pull
is used.
Customize how how changes are pushed ellipsis push
is used.
Customize output of ellipsis status
.
Customize how package is uninstalled. By default all symlinks are removed and
the package is deleted from $ELLIPSIS_PATH/packages
.
Customize which files are unlinked by your package.
Besides the default hook implementations which are available to you from your
ellipsis.sh
as hooks.<name>
, there are a number of useful functions and
variables which ellipsis exposes for you:
Lists all installed packages.
Executes command for each installed package.
Returns true if folder is empty.
Returns true if file exists.
Returns true if file is a symlink.
Returns true if file is a symlink pointing to an ellipsis package.
Returns true if file is a broken symlink.
Lists symlinks in a folder, defaulting to $ELLIPSIS_HOME
.
Creates a backup of an existing file, ensuring you don't overwrite existing backups.
Symlinks a single file into $ELLIPSIS_HOME
.
Symlinks all files in given folder into $ELLIPSIS_HOME
.
Clones a Git repo, identical to git clone
.
Identical to git pull
.
Identical to git push
.
Prints last commit's sha1 using git rev-parse --short HEAD
.
Prints commit's relative last update time.
Prints how far ahead a package is from origin.
Returns true if repository has changes.
Displays git diff --stat
.
Return absolute path to $1
.
Simple heuristic to determine if $1
is a path.
Replaces $HOME
with ~
Strips $ELLIPSIS_PACKAGES
from path.
Strip dot from hidden files/folders.
Returns one of cygwin
, freebsd
, linux
, osx
.
Returns true if command exists.
Prompts user $1
message and returns true if YES
or yes
is input.
Downloads and runs web-based shell script installers.
Alfred configuration files.
Atom configuration files.
Emacs configuration files.
Common dotfiles for various programs.
Irssi configuration.
iTerm2 configuration files.
Vim configuration based on vice framework.
Xmonad configuration.
Zsh configuration using zeesh! framework.
No stranger to dotfiles? Spent years hording complex configurations for esoteric and archaic programs? Have your own system for managing them using a bunch of scripts you've cobbled together over the years? I've been there, friend.
Luckily it's easy to convert your existing dotfiles into a shiny new ellipsis package:
$ export ELLIPSIS_USER=your-github-user
$ ellipsis new dotfiles
Initialized empty Git repository in /home/user/.ellipsis/packages/dotfiles/.git/
[master (root-commit) 5f5d2a9] Initial commit
2 files changed, 35 insertions(+)
create mode 100644 README.md
create mode 100644 ellipsis.sh
new package created at ~/.ellipsis/packages/dotfiles
$ ellipsis add dotfiles .*
mv ~/.vimrc dotfiles/vimrc
linking dotfiles/vimrc -> ~/.vimrc
mv ~/.zshrc dotfiles/zshrc
linking dotfiles/zshrc -> ~/.zshrc
A completion file for zsh is included. To use it add _ellipsis
to
your fpath
and ensure auto-completion is enabled:
fpath=($HOME/.ellipsis/comp $fpath)
autoload -U compinit; compinit
Pull requests welcome! New code should follow the existing style (and ideally include tests).
To suggest a feature or report a bug: http://github.com/zeekay/ellipsis/issues.