robbyrussell-node
Cross-shell robbyrussell theme written in JavaScript
Motivation
I'm developing 🚀⭐️ spaceship-zsh-theme which is an extremely powerful and customizable prompt for ZSH. It supports a lot of environments and tools to make you enjoy using it. However, there are plenty issues I faced: zsh is hard, dependency management is difficult, testing is near to impossible and so on.
This project is just a proof of concept. Definitely, that's not the best implementation, nevertheless, it opens interesting possibilities:
- high-level language — ZSH is nice, but not for programming. JavaScript or Python seems more comfortable for these cases.
- single code base — Single source code for all shells. The core logic is written in a high-level language while the shell-specific code is located in special files called adapters.
- cross-shell — different shells are too specific. Single code base on high-level language with unified interface gives us an ability to use it with any shell(fish, zsh, bash, sh, etc).
- cross-platform — things like
pkg
allows us to package prompt into binary and use it wherever we want, even without installed language runtime. - testable — high-level language and its infrastructure make it possible to test prompt components with tools like Mocha, Jest or tape (unlike traditional prompts which are usually untested).
- dependency management — NPM, RubyGems and PyPI store thousands of packages that could be used for special prompt's needs. It's also possible to install prompt itself with one of these package managers.
- asynchronous checks — the more synchronous checks you do, the slower prompt becomes. Things like
async/await
orPromise.all()
could perform environment checks concurrently, so we can achieve significant performance improvement.
Why JavaScript? Just because it's a high-level language which provides wide infrastructure with a good package manager, lots of packages and good community. It's quite fast and easy to make a simple working example.
Installation
npm
npm install -g robbyrussell
Done. This command should source the corresponding adapter for your shell. Just reload your terminal.
Binaries
If you don't have Node.js installed on your machine, you can download pre-built binaries with built-in Node.js version.
Use them in your shell configuration with adapters.
bash:
# BASH-specific adapter # set prompt PS1='$(robbyrussell_bash_adapter)'
zsh:
# ZSH-specific adapterrobbyrussell_zsh_adapter() { robbyrussell_previous_exit_code="$?" /path/to/robbyrussell $robbyrussell_previous_exit_code 'zsh'} # set promptPROMPT='$(robbyrussell_zsh_adapter)'
fish:
# FISH-specific adapterfunction robbyrussell_fish_adapter -d "a robbyrussell theme adapter for fish" set robbyrussell_previous_exit_code "$status" /path/to/robbyrussell $robbyrussell_previous_exit_code 'fish'end # set promptfunction fish_prompt # fish splits command substitutions on newlines # need to temporarily reset IFS to empty # @see: http://stackoverflow.com/a/34186172/5508862 set -l IFS robbyrussell_fish_adapterend
Configuration
Exposing the pormpt settings as environment variables is a known problem. This prompt reads a special configuration file from your home directory, which allows you to define more complex configs. A prompt automatically looks for ~/.prompt-config.js
or ~/.prompt-config.json
files. These files should export configuration object.
Important: A prompt needs to escape colors codes, otherwise it would behave incorrectly. This prompt includes patched
chalk
package with escape codes for currentprocess.env.SHELL
.
Default config looks like this:
// Patched for current shell chalk/chalk colorsconst styles = ; moduleexports = /** * Check git status asynchronously */ async: false /** * Prompt prefix and suffix */ prompt: open: stylesboldopen close: stylesboldclose + stylesresetclose /** * Status code */ status: char: '➜' success: stylesgreenopen failure: stylesredopen /** * Directory style */ dir: color: stylescyanopen /** * Git status styles */ git: indicator: stylesblueopen branch: stylesredopen dirty: stylesyellowopen dirtyChar: '✗' ;
License
MIT © Denys Dovhan