Getting started¶
Trying it out¶
Start luish from the shell you use now; exit (or Ctrl-D) goes back to it:
luish
If you’ve used a shell before, you should feel at home, luish should feel much like zsh.
The first run¶
If you installed luish with the install script and let it write the configuration, there is nothing to do here: it wrote the recommended configuration.
The first time luish starts in a terminal (when ~/.config/luish/ is missing or empty), it shows a menu (Up and
Down choose, Enter confirms; or press an item’s number):
Write the recommended configuration to
config.toml: Tab completion from the standard plugins (see below) and from luish-extra, its colour schemes, suggestions from the history as you type, and the conveniences of zsh and bash listed below. luish then runsplugin syncto fetch the plugins.Write an empty configuration: the recommended one, all commented out to turn on later, so that the menu isn’t shown again.
Add a personal plugin, as
plugin addtakes it: a GitHub repository (OWNER/REPOor its URL), another git URL, or a path.config.tomlthen has only that plugin, which can hold your whole configuration (see A personal plugin), and luish runsplugin syncto fetch it.Just start for now, writing nothing: the menu is shown again next time (as it is after Ctrl-C or Esc).
The rest of this page describes the files, to write or extend them yourself.
The recommended configuration¶
Without a configuration, every luish option is off, so luish behaves as dash does (as set -o and setopt show).
The recommended configuration turns on what most people expect from zsh or bash. It applies only to interactive
shells: luish reads config.toml only when it is interactive (a login shell reads only its [env]
and [path] tables), so scripts and sh -c keep POSIX’s behaviour. This is the file it writes:
# luish's configuration: see https://luish.readthedocs.io/en/latest/getting-started.html
# (written by luish). These settings apply only to interactive shells, not to scripts.
# Suggest the rest of the line from the history, in grey; Right or End accepts it.
[options.editor]
autosuggest = true
# zsh's % sequences in prompts: PS1='%~ %# ' shows the directory, then % (# for root).
[options.prompt]
percent = true
# Underline the arguments that name existing files as you type.
[options.highlight]
paths = true
# **/ matches any number of directories: ls **/*.rs
[options.glob]
star = true
# Brace expansion: cp f{,.bak} copies f to f.bak, and {1..3} is 1 2 3.
[options.expand]
braces = true
# A directory's name alone changes to it.
[options.cd]
auto = true
# cd remembers where it has been: dirs -v lists the directories, cd -2 goes back two.
[options.pushd]
auto = true
ignore_dups = true
silent = true
# !! for the previous command, !$ for its last word, ^old^new to run it with old replaced by new;
# a command typed with a space first isn't saved; each command is saved as soon as it runs.
[options.history]
expand = true
ignore_space = true
reduce_blanks = true
inc_append = true
# share = true # see the commands of the other shells as they run
# file = "~/.local/state/luish/history" # the default
# The plugins: plugin sync fetches them, and plugin update updates them.
[plugins.enabled]
std.completion = "*" # Tab completion for about 230 commands, and git
std.bash-completion = "*" # completion from bash-completion for the others
extra.completion.all = "*" # completion for about 270 more commands: science, bioinformatics, ...
extra.themes = "*" # colour schemes: style -c lists them, style -c NAME tries one
# luish-extra, under the name extra, at the newest release for this version of luish:
# https://github.com/luispedro/luish-extra
[plugins.available]
extra = { gh = "luispedro/luish-extra", release = "luish" }
# A colour scheme from extra.themes, as a pair: luish takes the one that fits the terminal's background.
# [style]
# colorscheme = { dark = "gruvbox-dark", light = "gruvbox-light" }
The bash-completion line is commented out if bash-completion isn’t installed, and file shows where the history
is saved on your system. __luish_internal default-config prints the file for your system.
Where the configuration goes¶
The configuration is in ~/.config/luish/ (or $XDG_CONFIG_HOME/luish/ if you set XDG_CONFIG_HOME), in these files and directories:
File |
What goes there |
|---|---|
|
Options, aliases, key bindings and the plugins to load |
|
Shell code for every interactive shell: variables and functions |
|
The environment, for login shells: |
|
Shell code that runs last, in every interactive shell: the prompt |
Create the directories:
mkdir -p ~/.config/luish/rc.d ~/.config/luish/login.d
Options, aliases and plugins: config.toml¶
Put this in ~/.config/luish/config.toml:
# Suggest the rest of the line from the history, in grey; Right or End accepts it.
[options.editor]
autosuggest = true
[options.history]
size = 10000 # commands to keep, in memory and in the file
share = true # commands typed in one terminal can be recalled in the others
ignore_space = true # a command that starts with a space is not saved
[options.cd]
auto = true # type a directory's name (or ..) to go there
[options.pushd]
auto = true # cd keeps the directories you were in: dirs -v lists them, cd +N goes back
ignore_dups = true
silent = true
[options.glob]
star = true # **/ matches any number of directories: ls **/*.c
bare_qualifiers = true # zsh's glob qualifiers: ls -d *(/) lists directories
[options.prompt]
percent = true # zsh's % sequences in PS1 (see the prompt below)
[alias]
ls = "ls --color=auto"
ll = "ls -lh"
la = "ls -lAh"
grep = "grep --color=auto"
g = "git"
gs = "git status"
# Global aliases are expanded anywhere in a command, not only at its start.
[alias.global]
"..." = "../.." # cd .../src
# G = "| grep" # ps aux G ssh
[bindkey]
Ctrl-Right = "forward-word"
Ctrl-Left = "backward-word"
# Tab completion for about 230 common commands, including git.
[plugins.enabled]
std.completion = "*"
The standard plugins¶
std.completion is the standard plugin for completion. It completes about 230 common commands (including ls, grep, tar, ssh, make, git, systemctl, cargo and docker).
You need to fetch the plugins once:
$ plugin sync
Fetching std
Locking std at 6a893bc (std/completion)
1 git source locked, 1 plugin enabled: std/completion
Variables and functions: rc.d¶
config.toml has no place for defining shell variables or functions, but we can add scripts to rc.d. For example, we can add function to make a directory and go into it, and change the characters that Ctrl-W and Alt-B stop at when deleting or moving by word:
# Ctrl-W and Alt-B stop at a /, so Ctrl-W deletes one directory of a path.
WORDCHARS='*?_-.[]~=&;!#$%^(){}<>'
# Make a directory and go into it.
mkcd() {
mkdir -p -- "$1" && cd -- "$1"
}
rc.d run after config.toml and the plugins, so they can change what these set.
The environment: login.d¶
Thie runs for login shells:
export PATH="$HOME/.local/bin:$PATH"
export EDITOR=vim PAGER=less
If your ~/.profile already has what you need, you can run it instead of repeating it:
. ~/.profile.
The prompt: luishrc¶
The prompt goes in ~/.config/luish/luishrc, which interactive shells run last, after the login files: on some
systems, such as Debian and Ubuntu, /etc/profile sets PS1, which would replace a prompt set in rc.d.
# The current directory in blue, the exit status in red if the last command failed, and % (# for root).
PS1='%[fg:blue]%[dir]%[fg_off] %([status]..%[fg:red][%[status]]%[fg_off] )%[prompt_char] '
This uses zsh-like prompt sequences, which is why we set option prompt.percent in config.toml. Luish’s also supports the zsh single-letter sequences, but we prefer the longer names as they are easier to read.
Prompts lists the sequences.
Checking the configuration¶
Open a new shell (or a new terminal) to use the configuration, and check it:
setopt # the options that are on
setopt -p history # the settings of a group
alias # the aliases
bindkey # the key bindings
plugin list-loaded # the plugins
Coming from bash or zsh¶
luish doesn’t read ~/.bashrc or ~/.zshrc. Aliases, functions and exported
variables from them usually work in luish as they are, and can be copied into
luishrc.
For backwards compatibility, luish supports many of bash’s and zsh’s options,
with the same names. For example, setopt share_history hist_ignore_space
needs no change from zsh, even though the luish names are history.share and
history.ignore_space.
Much of bash’s and zsh’s extensions to the shell language work too: arrays and
associative arrays, [[ ... ]], function, let, typeset,
${x/pattern/replacement}, ${!name} and zsh’s ${(j:,:)a[@]} flags (see
Shell language extensions).
shopt sets luish’s matching options (such as glob.star for globstar), and
is an error for bash options luish doesn’t have. Code that uses zstyle or
zsh’s other modules doesn’t work yet. Arrays are indexed from 0, as in bash and
in zsh’s sh mode, not from 1 as in native zsh.
If you have bash-completion
installed, as most distributions do, the std.bash-completion plugin can use
it to autocomplete arguments of the many commands that it knows (luish-native
completion takes precendence,though). To use it, add it
under [plugins.enabled], and run plugin sync again:
std.bash-completion = "*"
(plugin add std/bash-completion does both.)
Compared to luish-native completion, this is slower (each completion takes about 50 ms, as it runs bash), and gives no descriptions.
For about 270 more commands with luish-native completion, in bioinformatics (samtools, bwa, kraken2, …), science (snakemake, nextflow, pandoc, jupyter, …), desktop programs and Python tooling (pytest, ruff, …), add luish-extra:
$ plugin add luispedro/luish-extra extra
$ plugin add extra/completion/all
Next steps¶
A personal plugin: keep your configuration in a plugin of your own, to use the same one on every machine.
Usage: the command line, the prompt, line editing, history, Tab completion and the startup files in detail.
Plugins: other plugins, and writing your own.
Extensions: code in Rhai for your plugins: hooks, Tab completion and commands.
Extended globbing:
**/and zsh’s glob qualifiers, such asvi *(.om[0])to edit the newest file.helplists the built-in commands, andhelp NAMEshows the help for one of them.