A plugin is a FreSH script in ~/.fresh/plugins named <name>.plugin. It is
sourced into your shell at startup, so it can define aliases, functions and
variables. There is no manifest, no metadata and no install step.
plugin # list what is installed, loaded ones are marked
plugin load git # load one right now, for this session
rehash # reload the theme and every plugin after editing a filerehash re-sources whatever FRESH_THEME and FRESH_PLUGINS name, so editing
a plugin and running rehash applies it without opening a new shell. It adds
and replaces: an alias you deleted from the file stays until the shell
restarts, because sourcing a file cannot know what used to be in it.
Load them on every start with:
# ~/.freshrc
FRESH_PLUGINS="git dirs sys"Names are separated by spaces and loaded in that order.
g gs ga gc gco gb gd gl gp gpl
groot cd to the top of the repository
gclean list branches already merged
.. ... .... go up one, two, three levels
ll la l ls variations
mkcd dir create a directory and enter it
up go up one level and list
path print PATH
reload source ~/.freshrc
h c history, clear
ports listening sockets
psg name processes matching a name
e run $EDITOR
rc edit ~/.freshrc
edit x open a file with its default program
Create ~/.fresh/plugins/docker.plugin:
# docker shortcuts
alias d='docker'
alias dc='docker compose'
alias dps='docker ps'
alias di='docker images'
dsh() {
docker exec -it "$1" sh
}
dclean() {
docker container prune -f
docker image prune -f
}Add it:
FRESH_PLUGINS="git dirs sys docker"or try it without editing anything:
plugin load dockerAnything a script can do, because it is just a script. The useful patterns:
Aliases for short commands.
alias k='kubectl'Functions when you need arguments in the middle, or several steps.
backup() {
cp "$1" "$1.$(date +%Y%m%d)"
}Environment for tools you always want configured.
export EDITOR=nvim
export PAGER=catPATH additions, guarded so repeated loading does not stack up.
test -d "$HOME/tools" && export PATH="$HOME/tools;$PATH"Conditional setup, so a plugin can be harmless when the tool is missing.
if which cargo > nul 2>&1; then
alias cb='cargo build'
alias ct='cargo test'
fidescribe gives anything you add a page under help <name>, in the same
shape as the built in ones:
describe <name> <summary> [<usage>] [<detail>]dsh() {
docker exec -it "$1" sh
}
describe dsh "open a shell inside a running container" "dsh <container>"λ help dsh
dsh open a shell inside a running container
dsh <container>
<required> [optional] ... repeatable
Write the usage in the same notation the shell uses: <required>,
[optional], ... for repeatable. The fourth argument is a block of detail
printed under the usage line, which is where flags belong:
describe dclean "remove stopped containers and unused images" \
"dclean [-a]" \
" -a images with no tag as well
Asks for nothing and does not stop anything that is running."Aliases need no describe. help ll finds ll='ls -l' on its own and prints
the alias with the page for ls. Describe one anyway when the alias does
something the target's page does not explain.
Naming an existing command replaces its page, so a plugin that changes what
gs does can say so:
alias gs='git status --short --branch'
describe gs "the short status, with the branch line" "gs"Everything described shows up in the help overview under Described by
plugins, so a user can see what a plugin added without reading the file.
- Keep it fast. Everything in a plugin runs before your first prompt appears.
Avoid network calls, and avoid
$(...)that shells out to a slow program. - Do not print anything on load. A plugin that writes to the screen makes every new shell noisy.
- Do not change the current directory. Users do not expect a new shell to start somewhere unexpected.
- Guard anything machine specific with a
test, so the same plugin works on a machine where the tool is not installed. - Prefix helper functions that are not meant to be called directly, so they
do not collide with a real command. FreSH resolves a function before a
program on
PATH, so naming a functiongitwill shadow git everywhere.
Plugins are sourced after ~/.freshrc and after the theme. So:
- a plugin alias wins over an alias set earlier in
.freshrc - a plugin that sets
FRESH_PROMPTwins over the theme
If you want the opposite, drop FRESH_PLUGINS and load them by hand at the
top of .freshrc:
plugin load git dirs
alias gs='git status --short' # yours wins nowA plugin is one file with no dependencies, so sharing it is sending the file.
To install someone else's, copy it into ~/.fresh/plugins and add its name to
FRESH_PLUGINS. Read it first: it runs with your privileges every time you
open a shell.