1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
|
## 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 <program>` 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

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.

## 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.
|