Skip to content

Latest commit

 

History

History
241 lines (199 loc) · 12.9 KB

USER_DOC.md

File metadata and controls

241 lines (199 loc) · 12.9 KB

hellish — User Documentation

How to install it, use it, configure it, and check it is healthy. For building and hacking on it, see DEV_DOC.md; for the full manual, see the docs site.

What you get

service what it is
the shell an almost-POSIX shell that runs your bash scripts and muscle memory — hellish, hellish script.sh, hellish -c 'cmd'
prompt themes 29 named themes; prompt lists them, prompt <name> switches, prompt save <name> persists
plugin framework ~/.hellish/ with a conf manager — conf list, conf on|off <name>, hxp list; plus oh-my-zsh plugin support through the zsh dialect
completion tab completion for commands/files/variables; complete/compgen/compopt specs behind shopt -s progcomp
update channel a daily background check; update on demand, update --now to self-update

Install

One command (detects sudo rights, asks about plugins):

curl -fsSL https://raw.githubusercontent.com/Univers42/hellish/main/install.sh | sh
  • With sudo → installs to /usr/bin/hellish, adds it to /etc/shells, and offers to make it your login shell (chsh). Same as make my_shell.
  • Without sudo (42 school machines, shared boxes) → installs to ~/.local/bin/hellish, seeds ~/.hellishrc, and adds a small hook to your login shell's rc that execs hellish for interactive sessions — a real login shell, not an alias. Same as make user-install.
  • Non-interactive: sh install.sh --yes --plugins=all (or none, or a list: --plugins="git jump z"); force a mode with --user / --system.

From a source checkout: make user-install (no sudo) or make my_shell (sudo). Or just run it without installing: ./build/bin/hellish after make OPT=1 all.

Start and stop

  • Start: open a new terminal (if installed as a login shell), or run hellish.
  • Stop: exit or Ctrl-D. If stopped jobs exist, the first exit warns and the second obeys — like bash.
  • Skip the hook once (user-install route): HELLISH_NO_EXEC=1 bash. Disable it entirely: touch ~/.hellish-disable.

Uninstall

how you installed how to undo
install.sh / make my_shell make my-shell-uninstall (restores your login shell before removing the binary); make my-shell-purge also removes config + caches
install.sh / make user-install make user-uninstall — removes the rc hook and PATH block, leaves your ~/.hellishrc
npm npm uninstall -g hellish-shell

Configuration — where everything lives

path what it holds
~/.hellishrc your startup file (aliases, exports, shopt, PS1) — sourced by interactive shells only, never by scripts. Seeded from hellishrc.example, never overwritten
$XDG_CONFIG_HOME/hellish/rc.d/ drop-in config fragments, sourced in order before ~/.hellishrc — *.hsh with bash rules, *.zsh with zsh rules
$XDG_CONFIG_HOME/hellish/after.d/ the same, sourced after ~/.hellishrc and the plugin framework — where the installer puts your imported ~/.zshrc, so your own config has the last word
$XDG_CONFIG_HOME/hellish/themes/ the 29 prompt themes (yours to edit; edited ones are never clobbered by reinstall)
$XDG_CONFIG_HOME/hellish/plugins/ plugins as <name>/plugin.hsh
~/.hellish/ the plugin framework (conf, hxp, its plugins and state)
history file in $HOME, multi-line-safe; shopt -s lithist keeps newlines on recall
~/.cache/hellish update-check state (which release was already announced)

No passwords or credentials are stored anywhere — hellish has none to manage. The files above are the complete list of what an install touches.

Coming from zsh (every 42 account does): hellish does not run your ~/.zshrc. It is code written for zsh — one began with exec /bin/bash, one ran compinit and twenty zstyles — and a shell that is not zsh has no business executing it. The installer only appends its hook block to it (the # >>> hellish >>> … # <<< hellish <<< lines that hand the terminal over); everything else in that file stays zsh's. Bring across the lines you want: aliases and exports go in ~/.hellishrc as they are; a zsh-flavoured snippet (precmd() { vcs_info }, zstyle, PROMPT/RPROMPT) goes in ~/.config/hellish/rc.d/50-mine.zsh — the .zsh extension makes hellish read it with zsh rules — or under an emulate zsh first line in ~/.hellishrc. vcs_info, zstyle ':vcs_info:*', precmd/preexec, autoload and colors all work there.

If you want the whole file loaded anyway, ask for it by name: sh install.sh --zshrc writes ~/.config/hellish/after.d/90-zshrc.zsh, which sources ~/.zshrc in the zsh dialect, best effort, after ~/.hellishrc so your zsh config keeps the last word. A plain re-run of the installer switches it off again (kept as .off). In that mode source $ZSH/oh-my-zsh.sh is understood: hellish loads the plugins your plugins=(…) names and your $ZSH_CUSTOM/*.zsh — gst, gco and the rest of the git plugin work — skips what needs zsh's line editor (autosuggestions, syntax highlighting) silently, and keeps its own prompt (prompt picks one of 29); themes, lib/ and the completion system stay zsh's.

A syntax error in any file hellish loads is reported once, with the file and line, and the line itself — the same two lines bash prints — and the lines before it still run.

The prompt

PS1 is the prompt, and it is bilingual: bash's backslash escapes (\u, \w, \$, \[ \]…) and zsh's percent escapes (%~, %F{cyan}, %(?.a.b)…) work in the same string. PROMPT is the zsh spelling with zsh's exact rules, and wins when both are set; RPROMPT is the right prompt. The full escape list is section 1 of hellishrc.example, and wiki/interactive.md has the rest.

What is live at every render, and what is not:

in the prompt rendered?
$VAR, ${VAR}, ${VAR:-x}, $? and the other specials yes, every time the prompt is drawn
$((…)) yes
$(…) and backquotes no — the text stays on screen as written; it would fork on every redraw

Preview caveat: print -P formats its expanded input again using zsh's prompt escapes. If a variable contains % sequences, print -rP "[${V}]" can interpret them as prompt escapes even though the live prompt leaves the expanded value literal. Do not treat print -P output as an exact preview of variable-backed prompt segments; this mismatch is tracked in issue #134.

For a computed segment, set a variable from a hook and put the variable in the prompt. HELLISH_PRECMD_FUNCS runs once before each prompt (hellishrc.example, section 5b):

_branch() { BR=$(git branch --show-current 2>/dev/null); }
HELLISH_PRECMD_FUNCS=(_branch)
PS1='${BR:+($BR) }\w \$ '

prompt is a shell function, not a builtin. The installer seeds it into ~/.config/hellish/rc.d/40-prompt-switch.hsh, next to the 29 themes in ~/.config/hellish/themes/. type prompt says whether it is loaded; from a checkout, HELLISH_THEMES=share/themes; . share/rc.d/40-prompt-switch.hsh loads it by hand.

\A is not bash's 24-hour clock here. It is the animated glyph, and it was there first. A bash PS1 pasted in with \A shows the glyph — or nothing, since the animation is off by default — where bash shows 14:30. Write \D{%H:%M} or %T for the clock.

The animation is off by default, on purpose. HELLISH_ANIM=spinner (or pulse, ember) makes \A repaint the prompt row about ten times a second while the shell is idle. That repaint has been reported to corrupt the prompt on some terminals: an escape sequence printed as text (8;2;90;96;106m), or a cut glyph shown as �. It could not be reproduced on demand, so it ships off. If you turn it on and see that, HELLISH_ANIM=off is the fix.

Check that it works

hellish --version            # version + which repo the updater points at
echo 'echo ok $((6*7))' | hellish    # prints: ok 42
make doctor                  # from a checkout: which hellish PATH reaches,
                             # and whether `update` will need sudo
update                       # ask the release channel by hand
conf list                    # plugin framework: what is on and off

If a terminal ever misbehaves after an experiment: reset — and the escape hatches above get you back to your previous shell at any time.

Completing make targets

make <TAB> / make cl<TAB> completes target names from the Makefile in the current directory (also gmake, /usr/bin/make, and behind sudo, env X=1, &&, (; a wrapper option that takes an argument, as in sudo -u root make, falls back to filenames). The file is parsed in the shell itself; make is never run.

  • Files read: the first regular file of GNUmakefile, makefile, Makefile (GNU make's order, symlinks followed), at most 4 MiB. No such file, a directory, or an unreadable file means plain filename completion.
  • Offered: the names on target: / a b c: / a:: lines. Not offered: variable assignments, directives, recipe lines, define blocks, names with % or $, names starting with .; text after the colon is ignored.
  • include / -include / sinclude of literal file names are followed ONE level deep (what an included file includes is ignored). Changing only an included file does not refresh the cache; touch the Makefile.
  • Cache: the targets are reused while the Makefile's name, inode, mtime and size are unchanged (one stat per TAB).
  • A word starting with - or containing = or / keeps filename completion, and so does any make line with -C, --directory, -f, --file or --makefile before the cursor, or a prefix that matches no target (make out.txt).
  • A complete spec for make (under shopt -s progcomp) wins over all of this; complete -r make brings the targets back.

Knobs

variable effect
HELLISH_BANNER=0|1 welcome panel off / on
HELLISH_HISTORY_PREFIX=0|off Up/Down plain history; default is prefix search, read at every prompt
HELLISH_AUTOSUGGEST=1|on inline suggestion, off by default: the newest history line that starts with what you typed, shown dim after the cursor (see below); read at every prompt
HELLISH_SUGGEST_MAX=N how many of the newest history lines the suggestion looks at (default 1000; not a number, or below 1, is the default); read at every prompt
HELLISH_NO_UPDATE_CHECK=1 never check for updates, no badge
HELLISH_NO_ANIM=1 no startup animation
HELLISH_NO_EXEC=1 user-install hook: skip for this one session

Inline suggestion

With HELLISH_AUTOSUGGEST=1 (set it at the prompt or in the rc file) the newest history line that starts with what you have typed appears dim after the cursor. It is a hint, not part of the line: Right, End or Ctrl-F at the end of the line insert it; anywhere else, and when there is no hint, those keys do what they always did. Enter runs only what you typed, and the hint is wiped from the screen.

key with a hint without one
Right, End, Ctrl-F insert all of it forward-char / end-of-line
Alt-F, Ctrl-Right insert its next word; the rest stays as the hint forward-word
Alt-N show the next older, different matching line non-incremental forward search
Alt-P go back to the newer one shown before non-incremental reverse search

A word is the blanks at the front of the hint plus the run of characters up to the next space or tab (so -m, a/b, x=1 are one word each). Alt-N and Alt-P step through distinct lines (same full text offered once), look at no more than HELLISH_SUGGEST_MAX entries, ring the bell at the oldest and the newest end instead of wrapping, and start over from the newest match as soon as the line is edited. Right after Alt-N inserts the line shown, not the newest. A hint a zle widget set as POSTDISPLAY is not cycled or taken by words. In vi insert mode Alt-F / Alt-N / Alt-P work the same (no Ctrl-Right). unset HELLISH_AUTOSUGGEST (or =0) turns it off at the next prompt. A key you bound yourself (bind / bindkey / .inputrc) is never taken over.

Never suggested: a line with a newline, a tab or any other control character (an old printf '\e[31m' cannot repaint your prompt), and nothing at all while you search (Ctrl-R), in vi command mode, on a continuation prompt, with the cursor inside the line, or on a line that would not fit the terminal's width (the hint is cut at the edge, never wrapped). A right prompt (RPROMPT) is hidden while the hint reaches it and comes back when it does not.

For zsh widgets (zle -N), the variable POSTDISPLAY is the text shown after the cursor: read it in a widget to get the current hint, assign it (POSTDISPLAY=' <hint>') to show your own until the line next changes.