## What is this? Basta! is a small amount of GNU Bash code that maintains a scroll-protected status line at the bottom of the terminal. The status line shows the date, host name and current directory (possibly abbreviated to fit). This allows you to have very simple prompt: ::text PS1='\$ ' To use the code put the `basta.sh` file somewhere. Perhaps, turn it into a dot file in your home directory, under the name`~/.basta` Then, then source this file from some startup script, for instance by adding this line to `~/.bashrc`: ::text . ~/.basta.sh This requires Bash 4.4 or higher. ## Additional Installation Notes Note that `~/.bashrc' is loaded only for non-login shells. When Bash runs as a login shell, it runs `~/.bash_profile`. If customizations are placed in `~/.bashrc`, then `~/.bash_profile` must source `~/.bashrc`. That's one configuration style. Another style is to have customizations in a common file like `~/.bash_config` (not an official Bash name). This file is then sourced by both `~/.bashrc` and `~/.bash_profile`. Note that if Bash, when run as a login shell, does not find `~/.bash_profile`, it looks for `~/.bash_login`, and if that is missing, then `~/.profile`. If your environment uses these files, then you might want to integrate Basta via those instead. If you introduce `~/.bash_profile` into a user environment relying on `~/.bash_login`, you will suppress the use of `~/.bash_login`. If you rely on `~/.profile` for customization, that name is known to other shells. Since Basta works with Bash only, if you hook it into `~/.profile` you need a piece of code there to only run Basta if the shell is Bash. It makes sense to run Basta for both your login shell and for all recursive interactive shells which are non-login shells. Hence, it should be referenced from both `~/.bashrc` and from `~/.bash_profile`. Each Basta invocations in a new shell will create its own status line, as seen in the screenshot, helping you be aware that you are in a recursive session. The inactive status line below the topmost one are frozen: they continue to record the last time they were updated, and also show the working directory at that time. Unfortunately, applications sometimes clear the entire terminal, so that these frozen status lines disappear. The only way to refresh them is to return to their respective sessions (even if only temporarily vi a suspend operation). ## Reloading Basta supports hot reloading: if you make some changes to the code or fetch a minor update, you can just source the file again. ::text . /path/to/basta.sh However, if you're updating from a very old version to a much newer one, here is how to perform a deeper reload (assuming your `~/.bashrc` sources the Basta code): ::text basta.cleanup; exec bash -l I.e. run the Basta cleanup code explicitly and re-execute the login shell. The cleanup code is hooked to the `EXIT` trap, but that doesn't execute on exec. ## Temporarily Disabling Basta executes code for every new prompt, and when the signals SIGALRM and SIGWINCH are received. This activity can be a nuisance if you're debugging something else running in the same shell, particularly if you turn on `set -x` tracing. To get Basta temporarily out of the way run the command `basta.remove_hooks`. All that activity will stop; Basta will not update the display. To re-enable the activity, execute `basta.install_hooks`. ## Configuring Select applications for Full Screen With Basta running, terminal applications such as editors see a reduced terminal size. To make a selected applications, for example `vim`, use the full screen use the `basta.fullscreen` function as follows. ::text # e.g. in the ~/.bashrc file, after loading alias vim=`basta.fullscreen vim` When the alias is used, Basta will invoke the command in such a way that it uses the full screen. Create `basta.fullscreen ` alias for each program that is to use the full terminal. The `basta.fullscreen` function takes two options, `-f` and `-s`. They can be used together, and may be specified separately in any order or clumped as `-fs` or `-sf`. The `-f` option will force full screen mode even if the function's standard output is redirected such that it is not a terminal. By default, if standard output is redirected, `basta.fullscreen` just executes the specified command without preparing full screen mode. The default behavior is sensible; it prevents a race condition between `basta.fullscreen` coming out of fullscreen mode and restoring the status line, and a subsequent pipeline element still running, concurrently producing output to the terminal, resulting in a messed-up display. If the `-s` option is used, then then Basta will save and restore the terminal around the invocation of the program. This should only be used for full-screen programs that don't output any messages outside of their full-screen paradigm, which should persist in the terminal window. The `top` utility is a good target for this. Some versions of `top` do not save and restore the screen, with with `basta.fullscreen -s top` we get that behavior: ::text alias top='basta.fullscreen -s top' Now the `top` command restores the terminal upon quitting. Note that with the above alias, it becomes impossible to see the output of `top -h` on the terminal; the terminal is quickly restored after `top -h` produces output, making it look as if no output had been produced. ## Environment The multiple status line stacking in Basta relies on environment variables. Basta exports a set of numbered variables: `LC_basta_status_0`, `LC_basta_status_1`, ... and so on. Each recursive instances adds one more variable. The innermost recursive level of Basta refreshes the status lines of the outer levels from the contents of the lower-numbered variables. This is necessary because some applications clear from the cursor position to the end of the screen, an operation which disregards the scroll-protected region. Older version of Basta relied on looking at the current `LINES` variable relative to the full terminal size to determine the existence of an existing scroll-protected region, and add one line above it. The older versions were not capable of refreshing the previous status lines. The environment variables have a `LC_` prefix for the following reasons. In popular GNU/Linux distributions such as Ubuntu and Debian, the default OpenSSH configuration transmits environment variables which match the `LC_*` pattern. That is to say, the `ssh` client will send these variables via `SendEnv LC_*` and the server is prepared to receive them via `AcceptEnv LC_*`. Users of Basta on these systems don't have to do anything to get Basta recursion working across `ssh` sessions. If you run Basta on the remote host, and also on the remote machine, the remote one will add its status line above the status line(s) published by the local host. Users on systems that don't forward `LC_` environment variables through `ssh` will have to configure that to get it working. ## Screenshots ![Screenshot of Basta](screenshot.png) The clock actually updates. The code launches a background process which periodically the SIGALRM signal to the shell, whose trap calls the `basta.update_status` function. Here is another screenshot showing nested interactive shells, each taking up its own Basta! status line. The lines disappear one by one when the shells are exited. ![Screenshot of Nested Basta](screenshot-nested.png) ## License This is under distributed under a modified two-clause BSD license. See the license block at the bottom of the file. The second clause says that any binary code (as if that would exist for shell customization code, ha!) is not required to carry any copyright notice. # Bugs 1. When `basta.fullscreen` programs are used in a pipeline, whose other elements write to the terminal, those elements are not in the full screen context; their output may appear messed up. For instance `basta.fullscreen git log | cat`. The `cat` program executes asynchronously with regard to `basta.fullscreen`, producing output even while that function prepares the terminal in order to restore the status line. 2. Some impossible to solve race conditions situations in which Basta queries the terminal for information (like the current cursor position) and the user types input at around the same time. From time to time, there are glitches.